【android】利用BuildConfig.DEBUG来控制日志的输出

   作者:飞翔的猫咪    http://flyingcat2013.blog.51cto.com/7061638/1401367

原创作品,允许转载,转载时请务必以超链接形式标明文章  原始出处 、作者信息和本声明。否则将追究法律责任。 http://flyingcat2013.blog.51cto.com/7061638/1401367

前言

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


一种解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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的文件,内容非常简单:

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

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

1
2
3
4
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的菜单中可以看出来,分为手动和自动两种类型:

【android】利用BuildConfig.DEBUG来控制日志的输出_第1张图片     【android】利用BuildConfig.DEBUG来控制日志的输出_第2张图片

默认情况下,使用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模式,其主要代码如下。由于篇幅所限,这里不贴出运行截图,有需要的同学可以在文末地址免费下载任意调戏,别玩坏了:-)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//省略包声明、导入语句
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

本文出自 “飞翔的猫咪” 博客,请务必保留此出处http://flyingcat2013.blog.51cto.com/7061638/1401367



-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

在Android开发中,我们使用android.util.Log来打印日志,方便我们的开发调试。但是这些代码不想在发布后执行,我们并不想在软件发布后调试日志被其他开发者看到,现在我的方法是设置一个全局变量,标记软件为Debug模式还是Release模式。来看下代码:

public class Log {
    private static final boolean DEBUG = true;

    public static void i(String tag, String msg) {
        if (DEBUG)
            android.util.Log.i(tag, msg);
    }

    public static void e(String tag, String msg) {
        if (DEBUG)
            android.util.Log.e(tag, msg);
    }

    public static void d(String tag, String msg) {
        if (DEBUG)
            android.util.Log.d(tag, msg);
    }

    public static void v(String tag, String msg) {
        if (DEBUG)
            android.util.Log.v(tag, msg);
    }

    public static void w(String tag, String msg) {
        if (DEBUG)
            android.util.Log.w(tag, msg);
    }
}

这样打包发布之前只要改下DEBUG=false就行了,但是每次在发布之前都要手动去改这个变量,不是很方便,而且不排除开发者忘记改的情况。那么有没有更好更方便的做法呢?

ADT(r17)发布以后,Google为我们提供了一种新的调试机制,即BuildConfig.DEBUG。

ADT 17.0.0的New build features第二条如下描述:

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

即:新增了一个特性,允许开发者只在Debug模式下运行部分代码。Builds会生成一个叫做BuildConfig的类,该类包含一个名为DEBUG的常量,其常量值会依据开发者的Build类型自动设定。如此,便可以利用BuildConfig.DEBUG来实现只在Debug模式下运行的代码。

如果你的ADT已经更新到17及以上版本,可以尝试在Eclipse中新建一个Android工程,你会发现和R.java同级目录下多了一个叫做BuildConfig.java的类,其内容如下:

/** Automatically generated file. DO NOT MODIFY */
package com.boohee.one;

public final class BuildConfig {
    public final static boolean DEBUG = true;
}

这样只需要改动一行代码就ok了,

private static final boolean DEBUG = BuildConifg.DEBUG;

在上面提到,DEBUG会根据Build类型自动设定。那么Build类型又从哪里区分呢?很简单,点开Eclipse的Project菜单便可见分晓,如下图:

 

可见,Build类型分为Build Project和Build Automatically,即手动和自动。

需要注意的是,如果直接通过Eclipse运行Project,则不论Build是手动还是自动,DEBUG均不会被设定为false。这是为什么呢?这就牵涉到Android 签名的问题,这里只简单提一下,不赘述:直接通过Eclipse运行Project,Eclipse会在工程Build完毕后在bin目录下生成一个apk,这个apk的签名是调试模式(debug mode),和发布模式(release mode)签名生成的apk略有不同。如此,该问题产生原因便浮出水面。

此时肯定会有人说,直接使用Android Tools–>Export Signed Application Package导出的release mode apk,其DEBUG就是false。这是不对的。在生成Release版时,需要区分Build的类型。如果选择的是自动Build,那么DEBUG仍然会被设定为true。所以在生成Release版时,请按照下面这个步骤进行打包,BuildConfig.DEBUG会被修改为false:

  1. Project -> Build Automatically,即取消Build Automatically

  2. Project -> Clean

  3. Project -> Build

  4. Android Tools -> Export Android application


转自:http://stormzhang.github.io/android/2013/08/28/android-use-build-config/

你可能感兴趣的:(android,debug)