在开发Android应用程序时,我们可以在AndroidManifest.xml中设置其debug属性,
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" android:debuggable="true">
只有android:debuggable="true"时我们才可以在手机上调试Android程序。
但是当我们没在AndroidManifest.xml中设置其debug属性时:
使用Eclipse运行这种方式打包时其debug属性为true,使用Eclipse导出这种方式打包时其debug属性为法false.
在使用ant打包时,其值就取决于ant的打包参数是release还是debug.
因此在AndroidMainifest.xml中最好不设置android:debuggable属性值,而是由打包方式来决定其值。
从这里我们可以看出,假如反编译别人的apk之后,想要看别人的打印log,只需要在manifest文件中加上debug为true重新打打包就可以了哦。
我们也可以在Android应用程序中来判断当前应用是否处于debug状态来做一些操作
public static boolean isApkDebugable(Context context) { try { ApplicationInfo info= context.getApplicationInfo(); return (info.flags&ApplicationInfo.FLAG_DEBUGGABLE)!=0; } catch (Exception e) { } return false; }
在Android开发中,我们经常使用android.util.Log来打印日志,方便我们的开发调试。但是我们并不想在软件发布后调试日志被其他开发者看到,容易被反编译破解,标记软件为Debug模式还是Release模式就可以根据上面的判断来实现。如下:
private boolean DEBUG = isApkDebugable(context); public static void i(String tag, String msg) { if (DEBUG) android.util.Log.i(tag, msg); }
说到日志的打印,还有一种判断的方式,因为在ADT 17.0.0之后,Google为我们提供了一种新的调试机制,即BuildConfig.DEBUG。 Builds会生成一个叫做BuildConfig的类,该类包含一个名为DEBUG的常量,其常量值会依据开发者的Build类型自动设定。如此,便可以利用BuildConfig.DEBUG来实现只在Debug模式下运行的代码。
如果你的ADT已经更新到17及以上版本,可以尝试在Eclipse中新建一个Android工程,你会发现和R.java同级目录下多了一个叫做BuildConfig.java的类,其内容如下:
public final class BuildConfig { public final static boolean DEBUG = true; }
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
总结一下上面的日志的打印,感觉两种方式都可以的,但是我个人感觉后面的方式比较麻烦点,而且生成的时候容易出问题,步骤很重要,相对而言,在程序中判断debug属性,来打印日志这个还是比较容易的,但是这两种方式都不可能避免被别人反调试,毕竟重打包修改manifest文件的debug属性或者smali生成调试代码都是比较容易的。
我们也可以在Android应用程序中来判断当前其他应用程序是否处于debug状态
public static boolean isApkDebugable(Context context,String packageName) { try { PackageInfo pkginfo = context.getPackageManager().getPackageInfo( packageName, 1); if (pkginfo != null ) { ApplicationInfo info= pkginfo.applicationInfo; return (info.flags&ApplicationInfo.FLAG_DEBUGGABLE)!=0; } } catch (Exception e) { } return false; }