Android应用程序的发布 - 调试版本

Pij*_*usn 8 java android release build

在C++中,我通常会设置2个版本 - 分别使用DEBUGRELEASE预定义调试和发布.然后,我将使用这些定义来确定常量值,例如启用/禁用日志记录,服务器URL等.

现在,在Java/Android中,我在构建发布之前注释掉了一些内容.我可以说,这不是一个好方法.我可能会忘记一些事情

在构建发布版本(签名)或调试版本(未签名)时,确保不遗漏任何内容的常见做法是什么?

Ion*_*ers 16

如果从Eclipse运行应用程序,它将始终是一个调试.

导出应用程序时(Android工具 - >导出(未签名)签名的应用程序包)

如果你想动态了解它的发布或调试,你可以使用BuildConfig.DEBUG(它位于gen文件夹中,我不知道所有API级别是否支持它)

如下所示:

if (BuildConfig.DEBUG) {
    Log.d(TAG, "Text");
}
Run Code Online (Sandbox Code Playgroud)

如果查看生成的字节码,您将看到以下内容(在调试模式下):

public class Sample{

    private static final boolean LOG_ENABLED = true;

    public static void main(String args[]){
        if (BuildConfig.DEBUG){
            System.out.println("Hello World");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

生成以下字节码:

public class Sample extends java.lang.Object{
    public Sample();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return

    public static void main(java.lang.String[]);
      Code:
       0:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       3:   ldc #3; //String Hello World
       5:   invokevirtual   #4; //Method Java/io/PrintStream.println(Ljava/lang/String;)V
       8:   return

}
Run Code Online (Sandbox Code Playgroud)

如果BuildConfig.DEBUG为false

public class Sample extends java.lang.Object{
    public Sample();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return

    public static void main(java.lang.String[]);
      Code:
       0:   return
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ski 8

没有(默认情况下)Java的任何预处理器,所以#ifdef在编译时没有东西.但是如果您不介意在您的应用程序中保留调试代码,那么您可以使用以下代码检查应用程序是否在运行时发布或调试:

Boolean release = (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE);
Run Code Online (Sandbox Code Playgroud)

检查debuggable标志值.并且说flad会自动设置false为发布版本和true调试版本.

如果您想摆脱一些调试代码,可以尝试使用ProGuard去除某些类或方法.默认情况下,ProGuard仅参与构建发布版本的过程.

  • 我建议使用BuildConfig.DEBUG,因为这在编译时发生,您的解决方案适用于运行时.因此,日志代码将在包内.在编译时,java编译器不会将if语句中的代码考虑在内. (3认同)