如何在发布模式下调试 android 应用程序?

How to debug android app on release mode?

当我在发布模式下创建 apk 时,它会在启动时崩溃

当我为 proguard 启用 minifyEnabled 时出现问题,我通过将以下代码添加到 proguard-rules.pro

解决了这个问题
-keep class my.package.name.** {*;}

我认为原因是 proguard 删除了我的一些代码,但我不知道是哪一部分,因为它模糊了我的代码并且阅读 logcat 是无用的。 反正我理解 logcat 消息吗?

java.lang.NullPointerException: throw with null exception
    at e.a.z.a(:176)
    at i.n.run(:71)

您可以配置混淆器以获得更多信息。

-keepattributes SourceFile,LineNumberTable

这也会保留文件名和行号,因此您的 logcat 中会有更多数据。

此外,在您的调试版本上使用 minifyEnabled,这样混淆器将应用于您的调试版本,您将能够更好地调试它。

找到并修复问题后,即可将其从混淆器中移除。

因为这是一个生产 运行 应用程序,所以 NOT 妥协混淆(使用 keepattributes) 如果你只需要了解崩溃报告。

这在 android / google 准则中有详细说明。您可以上传由 proguard 创建的符号映射文件,允许崩溃报告 de-obfuscated.

映射文件通常在这里生成:

build/outputs/mapping/release/mapping.txt

这里有解释:https://developer.android.com/studio/build/shrink-code#decode-stack-trace

Proguard 有一个 Retrace API 描述如下:https://www.guardsquare.com/en/products/proguard/manual/retrace

然后上传到 google-play 以获得 de-obfuscated 报告:https://support.google.com/googleplay/android-developer/answer/6295281

如果您想 de-obfuscate 堆栈跟踪,请查看 this guide

如果您想 step-by-step 通过您的发布版本(与在调试中的方式相同),请尝试添加 debuggable true 到您的 gradle 配置 (app\build.gradle):

android
{
  buildTypes
  {
    release {
      proguardFiles 'your-proguard-config.pro'
      debuggable true   //<-- add this
    }
  }
}

Android 需要以下混淆器规则才能使 Android 应用正常运行:

-keep public class * extends android.app.Activity
-keep public class * extends androidx.appcompat.app.AppCompatActivity
-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.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

-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.content.Context {
   public void *(android.view.View);
   public void *(android.view.MenuItem);
}

-keepclassmembers class * implements android.os.Parcelable {
    static ** CREATOR;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}