前置文章
《Android 5.0 如何正确启用isLoggable(一)__使用详解》
概要
在上文《Android 5.0 如何正确启用isLoggable(一)__使用详解》中分析了isLoggable的使用方法,本文主要分析isLoggable实现原理以及user版系统root后永久enable isLoggable的原理,并使用脚本自动设置isLoggable相关属性。
本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处
isLoggable工作原理
isLoggable定义在frameworks/base/core/java/android/util/Log.java中:
/**
* Checks to see whether or not a log for the specified tag is loggable at the specified level.
*
* The default level of any tag is set to INFO. This means that any level above and including
* INFO will be logged. Before you make any calls to a logging method you should check to see
* if your tag should be logged. You can change the default level by setting a system property:
* 'setprop log.tag.<YOUR_LOG_TAG> <LEVEL>'
* Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will
* turn off all logging for your tag. You can also create a local.prop file that with the
* following in it:
* 'log.tag.<YOUR_LOG_TAG>=<LEVEL>'
* and place that in /data/local.prop.
*
* @param tag The tag to check.
* @param level The level to check.
* @return Whether or not that this is allowed to be logged.
* @throws IllegalArgumentException is thrown if the tag.length() > 23.
*/
public static native boolean isLoggable(String tag, int level); 而isLoggable的native实现则是在frameworks/base/core/jni/android_util_Log.cpp中:static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "isLoggable", "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
{ "println_native", "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },
};
static jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz, jstring tag, jint level)
{
//... ...省略
jboolean result = false;
if ((strlen(chars)+sizeof(LOG_NAMESPACE)) > PROPERTY_KEY_MAX) {
char buf2[200];
snprintf(buf2, sizeof(buf2), "Log tag "%s" exceeds limit of %zu charactersn",
chars, PROPERTY_KEY_MAX - sizeof(LOG_NAMESPACE));
jniThrowException(env, "java/lang/IllegalArgumentException", buf2);
} else {
// 调用本地isLoggalbe方法
result = isLoggable(chars, level);
}
env->ReleaseStringUTFChars(tag, chars);
return result;
} 从代码中可以看到,android_util_Log_isLoggable()的返回值取决于android_util_Log.cpp中的isLoggable()方法:#define LOG_NAMESPACE "log.tag."
static jboolean isLoggable(const char* tag, jint level) {
String8 key;
key.append(LOG_NAMESPACE);
key.append(tag);
char buf[PROPERTY_VALUE_MAX];
//获取属性log.tag.<Your_TAG>的值
if (property_get(key.string(), buf, "") <= 0) {
buf[0] = '