作者:飞翔的猫咪 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的菜单中可以看出来,分为手动和自动两种类型:

默认情况下,使用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/

更多相关文章

  1. [Android]Fragment源码分析(二) 状态
  2. Android里面classes.dex如何生成
  3. Android(安卓)studio 导出jar包并混淆和aar
  4. AndroidStudio上面最好用的插件
  5. android NDK JNI so文件的制作和使用
  6. 修改Android镜像文件 ramdisk.img、system.img、userdata.img获
  7. Android(安卓)studio将项目转换为jar文件
  8. 【转】android中onMeasure初看,深入理解布局之一!
  9. 第四章(2)Libgdx手工项目设置

随机推荐

  1. Android(安卓)UI属性大解
  2. 国内目前最全面的介绍——Android中的Bro
  3. android 建数据库 SQLite 存储sd 卡或者
  4. Android网络连接判断与处理
  5. 〖Android〗(how-to) fix k860/k860i bul
  6. Android应用程序进程启动过程的源代码分
  7. Python on Android
  8. android 中让activity全屏幕显示
  9. Android(安卓)EditText取消自动焦点获取
  10. android studio 3.1 Android(安卓)Device