作者:飞翔的猫咪 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,建议每次发布的时候按照下列步骤执行:
取消自动Build;
Clean(会丢弃所有编译好的状态);
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:
Project -> Build Automatically,即取消Build Automatically
Project -> Clean
Project -> Build
Android Tools -> Export Android application