发布 – debugging构buildAndroid应用程序

在C ++中,我通常会设置2个构build – 分别debugging和释放每个具有预定义的DEBUGRELEASE 。 然后,我将使用这些定义来确定常量值,如启用/禁用日志logging,服务器URL等。

现在,在Java / Android中,我build议发布之前注释掉一些东西。 这不是一个好方法,我可以告诉。 我可能会忘记一些事情

构build发行版本(签名)或debugging版本(无符号)时,什么是确保什么都不被遗忘的常见做法?

Solutions Collecting From Web of "发布 – debugging构buildAndroid应用程序"

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

 Boolean release = (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE); 

其中检查debuggable标志值。 并且所述flad自动设置为false ,以用于发布构build,并且对于debugging构build是true的。

如果你想摆脱一些debugging代码,你可以尝试使用ProGuard去除某些类或方法。 默认情况下,ProGuard只参与构build发布版本的过程。

如果您从Eclipse运行应用程序,它将始终是一个debugging。

当您导出应用程序时(Android工具 – >导出(un)签名的应用程序包)

如果你想dynamic地知道它的发行版或debugging,你可以使用BuildConfig.DEBUG(它位于gen文件夹中,我不知道这是否被所有API级别支持)

如下所示:

 if (BuildConfig.DEBUG) { Log.d(TAG, "Text"); } 

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

 public class Sample{ private static final boolean LOG_ENABLED = true; public static void main(String args[]){ if (BuildConfig.DEBUG){ System.out.println("Hello World"); } } } 

生成以下字节码:

 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 } 

如果BuildConfig.DEBUG是错误的

 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 } 

我通常创build一个单独的日志类,我设置一个静态DEBUGvariables。 现在我需要去得到一个生产版本是将DEBUGvariables设置为false。

 public class Log { public final static String LOGTAG = "APP NAME"; public static final boolean DEBUG = true; public static void v(String msg) { android.util.Log.v(LOGTAG, msg); } public static void e(String msg) { android.util.Log.e(LOGTAG, msg); } public static void d(String msg) { android.util.Log.d(LOGTAG, msg); } } 

logging –

 if(Log.DEBUG) Log.v("In some function x. Doing y."); 

我正在面对同样的问题,因为我每次运行的项目都是以debugging器模式打开的android应用程序,但问题解决了。

– 如果您在eclipse中工作,则必须使用Java EE透视图 – 相反,只需selectJava透视图。

– 清洁你的应用程序。 从设备上卸载应用程序。 – 重启你的设备(就像这样,没有caching存储) – 运行你的应用程序。

debugging器模式将不会显示这个时间。 复制bin文件夹中生成的apk,并在其他设备上试用

我find了一个正确模拟预处理指令的方法:

在我定义的Gradle buildTypes

 release { buildConfigField "boolean", "isDebug", "false" ... } debug { buildConfigField "boolean", "isDebug", "true" ... } 

然后,在我的代码中,我做如下:

 if (BuildConfig.isDebug) { ... do debug stuff ... } 

如果需要的话,当然是:

 else { ... do release stuff ... } 

这两个块都存在于debug APK中,但是在构buildrelease版本时, Proguard足够聪明以确定debug块可以被删除,因为它依赖于if (false) (也从结果代码中除去)。

你应该从debug块中调用一些特定于debugging的类,并且只能从那里调用它们,它们将从APK中剥离出来,因为它们被认为是未使用的 ,这也是一个有趣的地方:你的代码不能以它将使用的方式调节该代码。

我可以通过检查我的dumpmappingusage Proguard输出文件来确定所有这一切。