关于ADT中的BuildConfig.DEBUG

前言

在Android 应用程序开发中,不可避免地会常常输出各种调试信息,通常我们会使用android.util.Log类输出该类日志信息(这是推荐使用的方式)。然而,在项目发布的时候,我们常常需要关闭这些冗余的Log信息,手工关闭Log相当不方便,而且容易出现遗漏。


一种解决方案

package org.flyingcat.util;
import android.util.Log;
/**
 * @author Flyingcat
 * @create 2014-4-23
 * @version 1.0
 */
public class AppLog {
    private static final boolean LOG_DEBUG = true;
    public void d(String tag, String msg){
        if (LOG_DEBUG){
            Log.i(tag, msg);
        }
    }
    //省略重载方法……
}

这里展示了一种解决方案。这实际上是对标准Log的一个简单包装,在正式发布之前仍然需要手工将LOG_DEBUG变量的值设置为false,频繁发布的时候比较麻烦。


ADT的新特性

ADT 17.0.0以上版本在Build之后,会在R.java的相同路径下生成一个叫做BuildConfig.java的文件,内容非常简单:

/** Automatically generated file. DO NOT MODIFY */
package org.flyingcat.androidcodelib;
public final class BuildConfig {
    public final static boolean DEBUG = true;
}

在ADT的更新说明中是这样写的:

Added a feature that allows you to run some code only in debug mode.
Builds now generate a class called BuildConfig containing a DEBUG
constant that is automatically set according to your build type.
You can check the (BuildConfig.DEBUG) constant in your code to run debug-only functions.

大意是:

ADT17添加了一个新的特性,允许开发者仅在debug模式运行某些代码。每次Build的时候会新生成一个BuildConfig类,包含一个DEBUG常量,这个常量会在Build的时候根据Build类型自动生成。你可以在代码中测试(BuildConfig.DEBUG)常量来执行仅应在debug模式执行的代码。

但实际上,有些时候并不能达到效果,为什么呢?

很显然,我们可能使用方法不对。


如何确保关闭Log

既然Build的时候根据Build类型自动生成BuildConfig类,从Eclipse的Project的菜单中可以看出来,分为手动和自动两种类型:

关于ADT中的BuildConfig.DEBUG     关于ADT中的BuildConfig.DEBUG

默认情况下,使用Eclipse生成的项目中bin目录下的.apk文件,无论Build模式为哪种,DEBUG字段始终为true。这主要是由于Eclipse使用的是默认的android调试签名debug.keystore,这个签名被限制为debug mode,因此和release mode 的签名略有不同。

但是,这并不是说使用Android Tools->Export Signed Application Package生成的.apk就是release mode!之前我记得我看的某些博客中讲,只要使用AndroidTools导出的,DEBUG常量的值都是false,这是非常不正确和不负责任的,为此我还在客户面前闹过笑话::>_<::。【好吧你们知道我为什么要写这个了】

经过多次测试,如果使用的是自动build,在签名导出的时候生成的.apk很可能仍然是debug mode,即使是手动Build,偶尔也会出现这种情形【我使用的ADT版本为 22.3.0】。为了确保自己的.apk是release mode,建议每次发布的时候按照下列步骤执行:

  1. 取消自动Build;

  2. Clean(会丢弃所有编译好的状态);

  3. Export Signed Application Package.

有人说第三步应该是Build,之后才是Export,但导出的时候实际上会重新Build一次。一个明显的例子是在Clean之后gen包变空了,但是执行Export之后它的内容又回来了。因此我认为可以略去这一步。


可以使用一个简单的App测试发布方式是否为debug模式,其主要代码如下。由于篇幅所限,这里不贴出运行截图,有需要的同学可以在文末地址免费下载任意调戏,别玩坏了:-)。

//省略包声明、导入语句
public class MainActivity extends Activity {
    private static final String LOG_TAG = "MainActivity";
    private TextView textview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(LOG_TAG, "Hello, Flyingcat.");
        textview = (TextView) findViewById(R.id.textView1);
        if (BuildConfig.DEBUG){
            textview.setText("This release is debug mode!");
        }
        else{
            textview.setText("This release is not debug mode.");
        }
    }
}


附测试应用下载地址:http://down.51cto.com/data/1143476