gpt4 book ai didi

android - 在使用方法引用的 proguard 之后因 NoSuchMethodError 崩溃

转载 作者:塔克拉玛干 更新时间:2023-11-02 18:59:29 29 4
gpt4 key购买 nike

编译&proguard前的源码:

public class IntentSession extends BaseIntentSession {
@Override
public void onResume() {
super.onResume();
mExecutor.exec(getIntent(), this::finish);
}
}

compile&proguard 后的反编译代码:(使用 CFR 0_118 反编译)

public class a extends superA {

public void e() {
super.e();
this.c.a(this.j(), b.a((a)this)); // the problematic code here
}
}

现在是compile&proguard之后的关键代码,b类的反编译代码:

final class b implements c.a {
private a a;

b (a a1) {
this.a = a1;
}

static /* synthetic */ b a(final a a) {
return new b(a);
}

@LambdaForm.Hidden
public void a() {
this.a.finish();
}
}

它仍然引用了 finish() 方法,该方法已经被 proguard 混淆为 m()

我希望引用 finish() 方法被混淆为 m(),但这不是正在发生的事情,这是我的问题。

Proguard 没有警告我,它只会在遇到错误代码时在运行时因 NoSuchMethodError 而崩溃。所以不要告诉我添加像 -dontwarn java.lang.invoke.* 这样的 proguard 配置,我试过了但没有用。

也许在混淆过程中涉及的类的处理顺序是错误的,谁知道呢?

我不想在 finish() 方法上添加 @Keep 注释,这是一个糟糕的解决方案,我不得不担心它并在将来谨慎使用方法引用,所以我正在寻找最佳解决方案。

以下是我的 gradle 配置:

dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'me.tatarka:gradle-retrolambda:3.4.0'
classpath "com.fernandocejas.frodo:frodo-plugin:0.8.3"
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}

下面是我的proguard-rules.pro:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-ignorewarnings

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
native <methods>;
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}

-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

-dontwarn java.util.**
-keep class java.util.** {*; }

-dontwarn com.android.**
-keep class com.android.** { *; }

-dontwarn android.support.**
-keep class android.support.** { *; }

-keepattributes SourceFile, LineNumberTable

# end common config

##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

-dontwarn com.google.gson.**
-keep class com.google.gson.** { *; }

-dontwarn com.baidu.util.audiocore.**
-keep class com.baidu.util.audiocore.** { *; }

# Application classes that will be serialized/deserialized over Gson
##---------------End: proguard configuration for Gson ----------

# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}

-keep public class * implements java.io.Serializable {*;}
# end Serializable

# ----------------------------
-dontnote
-dontwarn com.xiaomi.push.service.XMPushService

#for speech sdk
-keep class com.orion.speech.** {*;}
-keep class com.orion.speech.audio.** {*;}
#end for speech sdk

#for xiaomi
-keep class PushReceiver {*;}
-keep class com.xiaomi.push.**{*;}
#end for xiaomi

#for retrofit
-dontwarn sun.misc.Unsafe
-dontwarn okio.**
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
#end for retrofit

#for lambda
-dontwarn java.lang.invoke.*
#end for lambda

#for okhttp
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
#end for okhttp

#for RxJava
-keep class rx.schedulers.Schedulers {
public static <methods>;
}
-keep class rx.schedulers.ImmediateScheduler {
public <methods>;
}
-keep class rx.schedulers.TestScheduler {
public <methods>;
}
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}

-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}

-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
# end for RxJava

#for bugly
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
#end for bugly

#----------------android

# this indicate the case of using APIs higher than minSDK (API 8)
-dontwarn android.**

# ---------------------------------------

# TODO: can be reduce if we have more understanding about Service and AIDL
-keep public class android.service.notification.** {*;}

-keepattributes *Annotation*,EnclosingMethod
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}


-keepclasseswithmembernames class * {
native <methods>;
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepattributes *Annotation*,EnclosingMethod,Signature

-keep interface android.content.pm.**{*;}
-keep class android.content.pm.**{*;}
-keep class android.os.Process{*;}

-dontwarn com.android.internal.os.*

-keep class android.support.v4.os.**{*;}

-keepclassmembers class * {
@android.support.v4 *;
}

# cmcm support
-keep class com.cmcm.support.jni.** { *; }

最佳答案

解决这些 -keep 无法修复的错误是真正的痛苦,而我在这些问题上取得进展的唯一方法是遵循以下策略:

  1. 找出错误是在混淆器周期的哪个阶段引入的(缩小、优化或混淆)
  2. 为该步骤添加/删除异常(exception)情况,从最广泛的排除范围到最窄的排除范围,直到问题再次出现

例如

验证这是否是一个优化问题

  1. 添加 -dontoptimize 而不是 -optimizations 字符串重建和测试
  2. 如果崩溃得到缓解,则在最高级别 !method/*, !code/*, !class/*, !field/* 向后处理优化排除类,直到您确定哪种排除会使问题消失
  3. 确定该类排除中的最小排除是什么(假设它是 !method/*,从它转到 !method/marking/* 然后如果尝试 !method/marking/final 也行得通。如果行得通,那么您已经找到了最小排除)

这很可能是您正在使用的某个库的 Proguard 规则中的错误,或者您正在使用的 Proguard 版本本身(我两者都看过)所以请尝试同时更新两者。

关于android - 在使用方法引用的 proguard 之后因 NoSuchMethodError 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43916814/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com