> 你还在为开发中频繁切换环境打包而烦恼吗?快来试试 Environment Switcher 吧!使用它可以在app运行时一键切换环境,而且还支持其他贴心小功能,有了它妈妈再也不用担心频繁环境切换了。[https://github.com/CodeXiaoMai/EnvironmentSwitcher](https://github.com/CodeXiaoMai/EnvironmentSwitcher)
项目中用到了Android-Universal-Image-Loader作为图片加载框架,但是在使用的过程中,发现如果图片加载失败就会在LogCat中打印出一大段异常的信息,如下图所示:
如果这种异常的Log太多,严重影响我们调试的过程中对目标信息的过滤,所以我们要关闭这个Log,但是这个库给我们留了一个坑啊。。。。
在使用ImageLoader之前,我们首先要配置一些基本信息。
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context)
.memoryCacheExtraOptions(480, 800) // default = device screen
// dimensions
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(2 * 1024 * 1024)).memoryCacheSize(2 * 1024 * 1024)
.diskCacheSize(200 * 1024 * 1024).diskCacheFileCount(2000)
.diskCacheFileNameGenerator(new Md5FileNameGenerator());
我们还会发现config有个这样的方法
config.writeDebugLogs();
进入这个方法,可以看到这个方法是ImageLoaderConfiguration.java中的一个方法,如下
public Builder writeDebugLogs() {
this.writeLogs = true;
return this;
}
代码很简单只是将this.writeLogs赋值为true,然后我们在找到声明writeLogs的地方,如下
private boolean writeLogs = false;
可以看到,这个属性默认为false,奇怪了,默认为false,那我不调用config.writeDebugLogs()这个方法,writeLogs这个属性不就是默认值false吗?,但是通过运行结果来看,好像不是想象中那样,该死的Log还是不停的在打印。。。。看来不调用这个方法也是不管用的。
接下来再找用到writeLogs这个属性的地方,通过查找发现,在ImageLoaderConfiguration的私有方法中,有这样一行代码。
L.writeDebugLogs(builder.writeLogs);
我们看到,调用了一个叫L类(这个类名起的真让人不可思议,应该是Log的首字母)的writeDebugLogs的方法。
public static void writeDebugLogs(boolean writeDebugLogs) {
L.writeDebugLogs = writeDebugLogs;
}
代码也很简单,是为L.writeDebugLogs赋值,这是声明的地方
private static volatile boolean writeDebugLogs = false;
当我找到这个地方时,我突然发现,这行代码的下面居然还有这个:
private staticvolatile boolean writeLogs = true;
难道这是打印log的开关吗?要是的话,那真是害死人啊。。。。再往下看一下代码,又发现了这样几个方法
public static void enableLogging() {
writeLogs(true);
}
public static void disableLogging() {
writeLogs(false);
}
public static void writeLogs(boolean writeLogs) {
L.writeLogs = writeLogs;
}
这几个方法是对writeLogs方法赋值的。再来看一下打印Log的方法
public static void d(String message, Object... args) {
if (writeDebugLogs) {
log(Log.DEBUG, null, message, args);
}
}
public static void i(String message, Object... args) {
log(Log.INFO, null, message, args);
}
public static void w(String message, Object... args) {
log(Log.WARN, null, message, args);
}
public static void e(Throwable ex) {
log(Log.ERROR, ex, null);
}
public static void e(String message, Object... args) {
log(Log.ERROR, null, message, args);
}
public static void e(Throwable ex, String message, Object... args) {
log(Log.ERROR, ex, message, args);
}
private static void log(int priority, Throwable ex, String message, Object... args) {
if (!writeLogs) return;
if (args.length > 0) {
message = String.format(message, args);
}
String log;
if (ex == null) {
log = message;
} else {
String logMessage = message == null ? ex.getMessage() : message;
String logBody = Log.getStackTraceString(ex);
log = String.format(LOG_FORMAT, logMessage, logBody);
}
Log.println(priority, ImageLoader.TAG, log);
}
仔细看一下上面几个方法,会发现,除了public static voidd(Stringmessage,Object... args)这个方法用到writeDebugLogs,其他几个方法,最后都会调用private staticvoidlog(intpriority,Throwable ex,String message,Object... args)方法。
记得我们的Log颜色都是红色的,也就是error级别的,显然writeDebugLogs这个只是负责打印Debug级别的log,结果很明确了,ImageLoader就是用过writeLogs这个属性,控制Log的打印的。我们通过调用L提供的disableLogging()就可以关闭Log了。