前言
本文主要给大家介绍了关于AndroID中能够作为Log开关的一些 *** 作及安全性的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
自定义常量
开发阶段利用 Log 日志方便代码调试是再常见不过的事情。出于安全考虑,这种做法仅限于 DeBUG 模式,Release 模式下打包发布时一定要关掉。所以在我们的项目中,一定会有一个工具类或者方法来控制 Log 日志的使用,比如:
public class LogUtils { public static final Boolean DEBUG_MODE = true; public static voID d(String message) { if (DEBUG_MODE) { Log.d("TAG",message); } } }
常见的做法便是像上面这样,自定义一个布尔类型的常量作为开关来控制是否打印日志。但是这种做法有一个弊端,那就是每次发布 Release 包时都需要手动修改这个常量的值为 false,然后下一次开发阶段再手动修改为 true。
虽然是很简单的手动修改 *** 作,但是也很容易忘记。那么有没有一种办法实现自动化管理呢?答案当然是有的,使用 BuildConfig 类。
BuildConfig
类似 R 资源文件,BuildConfig 也是在编译阶段,Gradle 插件自动生成的一个 class 文件。该文件包含一些帮助开发人员辨别当前 build 类型的常量信息。当然你也可以通过 Gradle 提供的定制功能向该文件里面添加其他辅助内容。这里我们看一下默认情况下,BuildConfig 文件都包含有哪些内容:
public final class BuildConfig { public static final boolean DEBUG = Boolean.parseBoolean("true"); public static final String APPliCATION_ID = "com.yifeng.sample"; public static final String BUILD_TYPE = "deBUG"; public static final String FLAVOR = ""; public static final int VERSION_CODE = 1; public static final String VERSION_name = "1.0";}
能够看出,都是一些大家很熟悉的信息。其中包括一个 DEBUG 常量,其值便可用于判断当前 build 类型。deBUG 模式下为 true,release 模式下为 false。所以,使用 BuildConfig.DEBUG
可以替代前面我们自定义的常量,实现自动管理 Log 日志的打印:
public static voID d(String message) { if (BuildConfig.DEBUG) { Log.d("TAG",message); }}
看上去貌似已经很完美了,但其实还是有瑕疵的。BuildConfig 类文件的生成依据于 Module,也就是说每一个 Module 编译时都会产生自己的这个文件。如果你的主 app module 使用其他依赖 module 中 BuildConfig 文件里面的 DEBUG 值,就需要多加注意。
默认情况下,library 的构建永远是以 Release 模式执行的,所以其 BuildConfig.DEBUG
值一定是 false!即使主 Module 使用 DeBUG 模式构建,也是如此。
那么,有没有办法修改 library Module 的默认构建方式呢?答案也是肯定的。打开对应 library 的 build.gradle 文件,添加这样一行配置代码:
androID { // 这里省略其他内容 publishNonDefault true}
即表示不使用默认构建方式,编译时也会自动生成其他 build 类型的 BuildConfig 类文件。你可以在相应 library 路径下查看配置该命令前后 BuildConfig 文件的生成情况,目录地址为:
libraryname/build/generated/source/buildConfig/ + deBUG/release
然后在我们的主 Module 依赖的时候同时引入 deBUG 和 release 两种配置,这里以 extras/PullToRefresh 作为 library 为例,看下依赖代码:
dependencIEs { releaseCompile project(path: ':extras:PullToRefresh',configuration: 'release') deBUGCompile project(path: ':extras:PullToRefresh',configuration: 'deBUG')}
如此这般,便可以解决前面提到的依赖 Module 问题。当然,如果你的项目比较简单,只是单一 Module,也就不存在这个问题。
但是如果项目中的依赖 Module 比较多的话,这种处理方式还是略显麻烦。你需要在用到的地方针对每个 Module 逐一处理。其实还有一种更好的解决方案,那就是使用 Manifest 清单文件中 application 标签里的 deBUGgable 属性。
ApplicationInfo
application 标签里有个 androID:deBUGgable
属性,表示当前应用是否可以被调试(一般不建议手动设置这个属性)。这个属性也会随着 build 类型自动改变。所以,利用这个特性也能判定应用是否处于 DeBUG 模式,比如:
public static boolean isDeBUG(Context context) { return (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;}
控制 Log 日志打印的开关,除了上面讲到的这些方式,其实还有别的方式。比如利用 Gradle 的灵活性在 build.gradle 文件中自定义一个 Boolean 变量,根据 build 类型动态赋值,也能达到我们的目的。
AndroID自定义Log开关
有时Log太多会影响速度,需要根据需要开关Log,而Android idE环境没有这个功能,起码Eclipse没有,那么我们可以写一个类将Log封装,通过调用这个类设置boolean变量,控制Log是否有效。
public class MLog{public static final boolean DEBUG = true;//开关控制public static voID i(String tag,String msg){if(DEBUG){Log.i(tag,msg);}public static voID e(String tag,String msg){if(DEBUG){Log.e(tag,msg);}//其它级别的同上...}
使用的时候直接调用MLog替换Log即可。
更安全的 Log 用法
前面所有这些做法都只是使 release 包不去显示 Log 日志,从而提高安全性。但是,有没有想过,如果 apk 被反编译的话,这些 Log 相关的代码还是能够别识别出来,别人只需要稍作修改,重新打包,依旧能够使 Log 重现。
当然,使用常量作为 LogUtils 中的判断条件的话,根据 proguard 的优化规则,在 Release 包中是不包含条件体中的 Log.d 等 *** 作代码的。关于这一点,可以自己反编译 apk 尝试看下。
然而,在其他调用 LogUtils 工具类的地方依旧暴露了我们的意图。所以,定义一个 LogUtils 类虽然提高了使用 Log 的效率,依旧解决不了 Log 安全的问题。相比而言,我们做了这么多努力只是稍微提高了一些安全的门槛而已。
所以,最好的办法就是,Release 包中不包含任何用于调试的 Log 代码(如果使用 LogUtils 的话,也包括 该类的调用)。也就是说,不使用 LogUtils 工具类封装,在任何需要的地方,不嫌麻烦的逐一添加判断条件:(可以使用 live Template 提高效率)
if (BuildConfig.DEBUG) { Log.d("TAG",message); }
这样,打包时,开启 proguard 后,Release 包会自动删除上面的代码,彻底根绝 Log 引发的安全问题。关于这一部分的细节 *** 作,可以参考这两篇文章:
Android Apk 文件反编译和重新打包的过程分析 如何安全地打印日志总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。
总结以上是内存溢出为你收集整理的Android中可以作为Log开关的一些 *** 作及安全性详解全部内容,希望文章能够帮你解决Android中可以作为Log开关的一些 *** 作及安全性详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)