How to correctly enable isLoggable in Android 5.0 (1) _ Usage Details, androidisloggable
What is isLoggable?
In the Android source code, we often see the following code:
//packages/apps/InCallUI/src/com/android/incallui/Log.javapublic static final String TAG = "InCall";public static final boolean DEBUG = android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);public static void d(String tag, String msg) { if (DEBUG) { android.util.Log.d(TAG, delimit(tag) + msg); }}//packages/apps/InCallUI/src/com/android/incallui/InCallPresenter.javaprivate InCallState startOrFinishUi(InCallState newState) { Log.d(this, "startOrFinishUi: " + mInCallState + " -> " + newState); //... ...}
StartOrFinishUi logs can be output normally only when the returned value of android. util. Log. isLoggable is true. When Will isLoggable return true? How can I enable isLoggable easily and quickly and make log output normal?
This article from http://blog.csdn.net/yihongyuelan reprint please be sure to indicate the source
IsLoggable Definition
What is isLoggable? IsLoggable is a method provided by android. util. Log. It is used to check whether the level of the specified TAG meets the output conditions. If yes, true is returned. Otherwise, false is returned. The definition of isLoggable in source code is as follows:
/** * 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);
You can see from the above definition:
1. The default level of isLoggable is android. util. Log. INFO;
2. Only level> = INFO can be output. That is, if level> = INFO, isLoggable returns true; otherwise, false;
3. You can use setprop log. tag. <YOUR_LOG_TAG> <LEVEL> to change the default log level, such as adb shell setprop log. tag. InCall D. You can also write these attributes to/data/local. prop in the form of log. tag. InCall = D;
4. If the tag length exceeds 23 characters, the IllegalArgumentException exception will be thrown;
Six levels of Log are defined in the android. util. Log class, as follows:
/** * Priority constant for the println method; use Log.v. */ public static final int VERBOSE = 2; /** * Priority constant for the println method; use Log.d. */ public static final int DEBUG = 3; /** * Priority constant for the println method; use Log.i. */ public static final int INFO = 4; /** * Priority constant for the println method; use Log.w. */ public static final int WARN = 5; /** * Priority constant for the println method; use Log.e. */ public static final int ERROR = 6; /** * Priority constant for the println method. */ public static final int ASSERT = 7;
The six levels correspond to logs of different levels. The size of the level value increases with the increase of the log weight.
IsLoggable enabling Method
As mentioned above, isLoggable is usually used in custom Log classes to determine whether to output logs, such as code:
//packages/apps/InCallUI/src/com/android/incallui/Log.javapublic static final String TAG = "InCall";public static final boolean DEBUG = android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);public static void d(String tag, String msg) { if (DEBUG) { android.util.Log.d(TAG, delimit(tag) + msg); }}//packages/apps/InCallUI/src/com/android/incallui/InCallPresenter.javaprivate InCallState startOrFinishUi(InCallState newState) { Log.d(this, "startOrFinishUi: " + mInCallState + " -> " + newState); //... ...}
To output logs in the startOrFinishUi () method, use the following method:
1. Change Log. d to android. util. Log. d;Use the android. util. Log class to replace the InCallUI custom Log class, recompile the system APP, and push it to the mobile phone;
②. Modify the DEBUG restrictions in com. android. incallui. Log;Set the DEBUG value to true directly or comment out if (DEBUG ). You can also set isLoggable (TAG, android. util. log. android. util. log. DEBUG to android. util. log. INFO, which increases the log level so that isLoggable () returns true and the DEBUG value is true;
③. Set the attribute value of log. tag. InCall;Use adb shell setprop log. tag. inCall D, or set "log. tag. inCall = D "Write/data/local. prop (excluding quotation marks, such as local. if the prop does not exist, you must create it by yourself and set the permission to 644 ). According to the description in the definition, setting the attribute value requires restarting the InCallUI process before the method is called. By modifying the attribute value, the isLoggable () returns true and the DEBUG value is true.
The first method is to directly modify the code, which is simple and crude. However, if there are many changes, it is troublesome and the code needs to be re-compiled.
The second method is to unify the modification points, but, like the first method, it also needs to be re-compiled.
The third method is to use attributes to make isLoggable return true. This method is convenient and suitable for devices of user/userdebug/eng versions. In this way, you need to set log. tag. InCall before the method is called, through the Code:
public static final boolean DEBUG = android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
As you can know, DEBUG is a static variable, so when the Log class is loaded, its value has been set. If you want to make isLoggable return true, setprop needs to be set before the Log class is loaded. Therefore, you need to restart the corresponding process after using setprop, as shown in com. android. incallui. But some code in the framework also uses isLoggable. The framework belongs to every process. How can I restart the framework? You can use:
adb shell stopadb shell start
Adb shell stop will kill the zygote process and all child processes incubated by zygote. Adb shell start restarts the zygote process, and other Android core processes are started by the zygote process. When zygote restarts, the framework resources are reloaded, and the attributes are set. This method is simple, but when the device restarts, all configured log. tag. <TAG> will be invalid. If you want to enable it again, you need to reset it.
You can also. tag. inCall = D add to/data/local. in the prop file, this method is similar to setprop and is used to set the property value. However, the advantage of this method is that the log is restarted after the device is set. tag. inCall is still valid. However, only the userdebug/eng version can modify the/data/local. prop file because of the/data directory permission control.
Summary
Shows how to enable isLoggable:
Figure 1 Comparison of isLoggable enabling schemes
If you only want to enable the isLoggable method of a process, setting properties through setprop is a good choice. to restart the device, you need to set/data/local. prop, but the/data directory can be written only in the userdebug/eng version.If you want to set the log. tag attribute in user edition and remain valid after restart, you can use the following methods:
1. Obtain the root permission of the user edition system;
2. append log. tag. InCall = D to the/system/build. prop file;
3. adb reboot restarts the device;
In the above solution, you may wonder why the user version does not directly modify/data/local. prop since it has obtained the root permission? This is because ro. debuggable = 0 for the user version, so the/data/local. prop file will not be read when the system starts, and the setting of the log. tag attribute will not take effect. The detailed principles will be discussed in the next article "how to correctly enable isLoggable (1) _ Principle Analysis in Android 5.0.