| 本帖最后由 心愿wish 于 2013-9-30 10:41 编辑 
 
 | 158 | * Checks to see whether or not a log for the specified tag is loggable at the specified level. | 
 
 | 160 | *  The default level of any tag is set to INFO. This means that any level above and including | 
 
 | 161 | *  INFO will be logged. Before you make any calls to a logging method you should check to see | 
 
 | 162 | *  if your tag should be logged. You can change the default level by setting a system property: | 
 
 | 163 | *      'setprop log.tag.<YOUR_LOG_TAG> <LEVEL>' | 
 
 | 164 | *  Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will | 
 
 | 165 | *  turn off all logging for your tag. You can also create a local.prop file that with the | 
 
 
 | 167 | *      'log.tag.<YOUR_LOG_TAG>=<LEVEL>' | 
 
 | 168 | *  and place that in /data/local.prop. | 
 
 
 | 170 | * @param tag The tag to check. | 
 
 | 171 | * @param level The level to check. | 
 
 | 172 | *  Whether or not that this is allowed to be logged. | 
 
 | 173 | * @throws IllegalArgumentException is thrown if the tag.length() > 23. | 
 
 
 | 175 | public static native boolean isLoggable(String tag, int level); | 
 
 
 | 177 | * Send a { #WARN} log message and log the exception. | 
 
 | 178 | * @param tag Used to identify the source of a log message.  It usually identifies | 
 
 | 179 | *        the class or activity where the log call occurs. | 
 
 | 180 | * @param tr An exception to log | 
 
 
 | 182 | public static int w(String tag, Throwable tr) { | 
 
 | 183 | return println_native(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr)); | 
 
 
 
 | 186 | * Send an {@link #ERROR} log message. | 
 
 | 187 | * @param tag Used to identify the source of a log message.  It usually identifies | 
 
 | 188 | *        the class or activity where the log call occurs. | 
 
 | 189 | * @param msg The message you would like logged. | 
 
 
 | 191 | public static int e(String tag, String msg) { | 
 
 | 192 | return println_native(LOG_ID_MAIN, ERROR, tag, msg); | 
 
 
 
 | 195 | * Send a {@link #ERROR} log message and log the exception. | 
 
 | 196 | * @param tag Used to identify the source of a log message.  It usually identifies | 
 
 | 197 | *        the class or activity where the log call occurs. | 
 
 | 198 | * @param msg The message you would like logged. | 
 
 | 199 | * @param tr An exception to log | 
 
 
 | 201 | public static int e(String tag, String msg, Throwable tr) { | 
 
 | 202 | return println_native(LOG_ID_MAIN, ERROR, tag, msg + '/n' + getStackTraceString(tr)); | 
 
 
 
 | 205 | * What a Terrible Failure: Report a condition that should never happen. | 
 
 | 206 | * The error will always be logged at level ASSERT with the call stack. | 
 
 | 207 | * Depending on system configuration, a report may be added to the | 
 
 | 208 | * {@link Android.os.DropBoxManager} and/or the process may be terminated | 
 
 | 209 | * immediately with an error dialog. | 
 
 | 210 | * @param tag Used to identify the source of a log message. | 
 
 | 211 | * @param msg The message you would like logged. | 
 
 
 | 213 | public static int wtf(String tag, String msg) { | 
 
 | 214 | return wtf(tag, msg, null); | 
 
 
 
 | 217 | * What a Terrible Failure: Report an exception that should never happen. | 
 
 | 218 | * Similar to {@link #wtf(String, String)}, with an exception to log. | 
 
 | 219 | * @param tag Used to identify the source of a log message. | 
 
 | 220 | * @param tr An exception to log. | 
 
 
 | 222 | public static int wtf(String tag, Throwable tr) { | 
 
 | 223 | return wtf(tag, tr.getMessage(), tr); | 
 
 
 
 | 226 | * What a Terrible Failure: Report an exception that should never happen. | 
 
 | 227 | * Similar to {@link #wtf(String, Throwable)}, with a message as well. | 
 
 | 228 | * @param tag Used to identify the source of a log message. | 
 
 | 229 | * @param msg The message you would like logged. | 
 
 | 230 | * @param tr An exception to log.  May be null. | 
 
 
 | 232 | public static int wtf(String tag, String msg, Throwable tr) { | 
 
 | 233 | tr = new TerribleFailure(msg, tr); | 
 
 | 234 | int bytes = println_native(LOG_ID_MAIN, ASSERT, tag, getStackTraceString(tr)); | 
 
 | 235 | RuntimeInit.wtf(tag, tr); | 
 
 
 
 
 | 239 | * Handy function to get a loggable stack trace from a Throwable | 
 
 | 240 | * @param tr An exception to log | 
 
 
 | 242 | public static String getStackTraceString(Throwable tr) { | 
 
 
 
 
 | 246 | StringWriter sw = new StringWriter(); | 
 
 | 247 | PrintWriter pw = new PrintWriter(sw); | 
 
 | 248 | tr.printStackTrace(pw); | 
 
 | 249 | return sw.toString(); | 
 
 
 
 | 252 | * Low-level logging call. | 
 
 | 253 | * @param priority The priority/type of this log message | 
 
 | 254 | * @param tag Used to identify the source of a log message.  It usually identifies | 
 
 | 255 | *        the class or activity where the log call occurs. | 
 
 | 256 | * @param msg The message you would like logged. | 
 
 | 257 | * @return The number of bytes written. | 
 
 
 | 259 | public static int println(int priority, String tag, String msg) { | 
 
 | 260 | return println_native(LOG_ID_MAIN, priority, tag, msg); | 
 
 
 | 262 | /** @hide */ public static final int LOG_ID_MAIN = 0; | 
 
 | 263 | /** @hide */ public static final int LOG_ID_RADIO = 1; | 
 
 | 264 | /** @hide */ public static final int LOG_ID_EVENTS = 2; | 
 
 | 265 | /** @hide */ public static final int LOG_ID_SYSTEM = 3; | 
 
 | 266 | /** @hide */ public static native int println_native(int bufID, | 
 
 | 267 | int priority, String tag, String msg); | 
 
 
 我们看到所有代码都是调用public static native int println_native(int bufID,
 int priority, String tag, String msg);来实现输出的,这个函数的实现就是C++,调用的方式就是JNI
 我们看一下对应的jni代码froyo/frameworks/base/core/jni/Android_util_Log.cpp,最终调用的输出函数是
 
 
 | 02 | * In class Android.util.Log: | 
 
 | 03 | *  public static native int println_native(int buffer, int priority, String tag, String msg) | 
 
 
 | 05 | static jint Android_util_Log_println_native(JNIEnv* env, jobject clazz, | 
 
 | 06 | jint bufID, jint priority, jstring tagObj, jstring msgObj) | 
 
 
 | 08 | const char* tag = NULL; | 
 
 | 09 | const char* msg = NULL; | 
 
 
 
 | 12 | npeClazz = env->FindClass("java/lang/NullPointerException"); | 
 
 | 13 | assert(npeClazz != NULL); | 
 
 | 14 | env->ThrowNew(npeClazz, "println needs a message"); | 
 
 
 
 | 17 | if (bufID < 0 || bufID >= LOG_ID_MAX) { | 
 
 
 | 19 | npeClazz = env->FindClass("java/lang/NullPointerException"); | 
 
 | 20 | assert(npeClazz != NULL); | 
 
 | 21 | env->ThrowNew(npeClazz, "bad bufID"); | 
 
 
 
 
 | 25 | tag = env->GetStringUTFChars(tagObj, NULL); | 
 
 | 26 | msg = env->GetStringUTFChars(msgObj, NULL); | 
 
 | 27 | int res = __Android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg); | 
 
 
 | 29 | env->ReleaseStringUTFChars(tagObj, tag); | 
 
 | 30 | env->ReleaseStringUTFChars(msgObj, msg); | 
 
 
 
 
 当然我们发现最终输出是
 
 | 1 | int res = __Android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg); | 
 
 
 用力grep了一下代码,结果如下
 
 | 1 | ./system/core/include/cutils/log.h:int __Android_log_buf_write(int bufID, int prio, const char *tag, const char *text); | 
 
 | 2 | ./system/core/liblog/logd_write.c:int __Android_log_buf_write(int bufID, int prio, const char *tag, const char *msg) | 
 
 | 3 | ./system/core/liblog/logd_write.c:    return __Android_log_buf_write(bufID, prio, tag, buf); | 
 
 
 
 这个就是和Android专用驱动进行通信的方式,这个分析下去就有点深了,后面分析。
 以上三个小节分析了Android的JAVA环境,我这里都是简单的抛砖引玉,希望能给大家一点大体的指引,其他修行靠大家了,能成为是一个android程序员是多么幸福的事情,各位已经在幸福中了,我什么时候也可以幸福一把??
 
 
 |