前置文章
《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] = '