




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在开发Android应用程序时,少不了使用Log来监控和调试程序的执行。在上一篇文章Android日志系统驱动程序Logger源代码分析中,我们分析了驱动程序Logger的源代码,在前面的文章浅谈Android系统开发中Log的使用一文,我们也简单介绍在应用程序中使Log的方法,在这篇文章中,我们将详细介绍Android应用程序框架层和系统运行库存层日志系统的源代码,使得我们可以更好地理解Android的日志系统的实现。 我们在Android应用程序,一般是调用应用程序框架层的Java接口(android.util.Log)来使用日志系统,这个Java接口通过JNI方法和系统运行库最终调用内核驱动程序Logger把Log写到内核空间中。按照这个调用过程,我们一步步介绍Android应用程序框架层日志系统的源代码。学习完这个过程之后,我们可以很好地理解Android系统的架构,即应用程序层(Application)的接口是如何一步一步地调用到内核空间的。 一. 应用程序框架层日志系统Java接口的实现。 在浅谈Android系统开发中Log的使用一文中,我们曾经介绍过Android应用程序框架层日志系统的源代码接口。这里,为了描述方便和文章的完整性,我们重新贴一下这部份的代码,在frameworks/base/core/java/android/util/Log.java文件中,实现日志系统的Java接口:view plain1. .2. 3. publicfinalclassLog4. 5. .6. 7. /*8. *Priorityconstantfortheprintlnmethod;useLog.v.9. */10. publicstaticfinalintVERBOSE=2;11. 12. /*13. *Priorityconstantfortheprintlnmethod;useLog.d.14. */15. publicstaticfinalintDEBUG=3;16. 17. /*18. *Priorityconstantfortheprintlnmethod;useLog.i.19. */20. publicstaticfinalintINFO=4;21. 22. /*23. *Priorityconstantfortheprintlnmethod;useLog.w.24. */25. publicstaticfinalintWARN=5;26. 27. /*28. *Priorityconstantfortheprintlnmethod;useLog.e.29. */30. publicstaticfinalintERROR=6;31. 32. /*33. *Priorityconstantfortheprintlnmethod.34. */35. publicstaticfinalintASSERT=7;36. 37. .38. 39. publicstaticintv(Stringtag,Stringmsg)40. returnprintln_native(LOG_ID_MAIN,VERBOSE,tag,msg);41. 42. 43. publicstaticintv(Stringtag,Stringmsg,Throwabletr)44. returnprintln_native(LOG_ID_MAIN,VERBOSE,tag,msg+n+getStackTraceString(tr);45. 46. 47. publicstaticintd(Stringtag,Stringmsg)48. returnprintln_native(LOG_ID_MAIN,DEBUG,tag,msg);49. 50. 51. publicstaticintd(Stringtag,Stringmsg,Throwabletr)52. returnprintln_native(LOG_ID_MAIN,DEBUG,tag,msg+n+getStackTraceString(tr);53. 54. 55. publicstaticinti(Stringtag,Stringmsg)56. returnprintln_native(LOG_ID_MAIN,INFO,tag,msg);57. 58. 59. publicstaticinti(Stringtag,Stringmsg,Throwabletr)60. returnprintln_native(LOG_ID_MAIN,INFO,tag,msg+n+getStackTraceString(tr);61. 62. 63. publicstaticintw(Stringtag,Stringmsg)64. returnprintln_native(LOG_ID_MAIN,WARN,tag,msg);65. 66. 67. publicstaticintw(Stringtag,Stringmsg,Throwabletr)68. returnprintln_native(LOG_ID_MAIN,WARN,tag,msg+n+getStackTraceString(tr);69. 70. 71. publicstaticintw(Stringtag,Throwabletr)72. returnprintln_native(LOG_ID_MAIN,WARN,tag,getStackTraceString(tr);73. 74. 75. publicstaticinte(Stringtag,Stringmsg)76. returnprintln_native(LOG_ID_MAIN,ERROR,tag,msg);77. 78. 79. publicstaticinte(Stringtag,Stringmsg,Throwabletr)80. returnprintln_native(LOG_ID_MAIN,ERROR,tag,msg+n+getStackTraceString(tr);81. 82. 83. .84. /*hide*/publicstaticnativeintLOG_ID_MAIN=0;85. /*hide*/publicstaticnativeintLOG_ID_RADIO=1;86. /*hide*/publicstaticnativeintLOG_ID_EVENTS=2;87. /*hide*/publicstaticnativeintLOG_ID_SYSTEM=3;88. 89. /*hide*/publicstaticnativeintprintln_native(intbufID,90. intpriority,Stringtag,Stringmsg);91. 定义了27一共6个日志优先级别ID和4个日志缓冲区ID。回忆一下Android日志系统驱动程序Logger源代码分析一文,在Logger驱动程序模块中,定义了log_main、log_events和log_radio三个日志缓冲区,分别对应三个设备文件/dev/log/main、/dev/log/events和/dev/log/radio。这里的4个日志缓冲区的前面3个ID就是对应这三个设备文件的文件描述符了,在下面的章节中,我们将看到这三个文件描述符是如何创建的。在下载下来的Android内核源代码中,第4个日志缓冲区LOG_ID_SYSTEM并没有对应的设备文件,在这种情况下,它和LOG_ID_MAIN对应同一个缓冲区ID,在下面的章节中,我们同样可以看到这两个ID是如何对应到同一个设备文件的。 在整个Log接口中,最关键的地方声明了println_native本地方法,所有的Log接口都是通过调用这个本地方法来实现Log的定入。下面我们就继续分析这个本地方法println_native。 二.应用程序框架层日志系统JNI方法的实现。 在frameworks/base/core/jni/android_util_Log.cpp文件中,实现JNI方法println_native:view plain1. /*/device/libs/android_runtime/android_util_Log.cpp2. *3. *Copyright2006,TheAndroidOpenSourceProject4. *5. *LicensedundertheApacheLicense,Version2.0(theLicense);6. *youmaynotusethisfileexceptincompliancewiththeLicense.7. *YoumayobtainacopyoftheLicenseat8. *9. */licenses/LICENSE-2.010. *11. *Unlessrequiredbyapplicablelaworagreedtoinwriting,software12. *distributedundertheLicenseisdistributedonanASISBASIS,13. *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.14. *SeetheLicenseforthespecificlanguagegoverningpermissionsand15. *limitationsundertheLicense.16. */17. 18. #defineLOG_NAMESPACElog.tag.19. #defineLOG_TAGLog_println20. 21. #include22. #include23. #include24. #include25. 26. #includejni.h27. #includeutils/misc.h28. #includeandroid_runtime/AndroidRuntime.h29. 30. #defineMIN(a,b)(aGetStringUTFChars(tag,NULL);74. 75. if(strlen(chars)+sizeof(LOG_NAMESPACE)PROPERTY_KEY_MAX)76. jclassclazz=env-FindClass(java/lang/IllegalArgumentException);77. charbuf2200;78. snprintf(buf2,sizeof(buf2),Logtag%sexceedslimitof%dcharactersn,79. chars,PROPERTY_KEY_MAX-sizeof(LOG_NAMESPACE);80. 81. /releasethechars!82. env-ReleaseStringUTFChars(tag,chars);83. 84. env-ThrowNew(clazz,buf2);85. returnfalse;86. else87. strncpy(key,LOG_NAMESPACE,sizeof(LOG_NAMESPACE)-1);88. strcpy(key+sizeof(LOG_NAMESPACE)-1,chars);89. 90. 91. env-ReleaseStringUTFChars(tag,chars);92. 93. len=property_get(key,buf,);94. intlogLevel=toLevel(buf);95. return(logLevel=0&level=logLevel)?true:false;96. #endif/*HAVE_ANDROID_OS*/97. 98. 99. /*100. *Inclassandroid.util.Log:101. *publicstaticnativeintprintln_native(intbuffer,intpriority,Stringtag,Stringmsg)102. */103. staticjintandroid_util_Log_println_native(JNIEnv*env,jobjectclazz,104. jintbufID,jintpriority,jstringtagObj,jstringmsgObj)105. 106. constchar*tag=NULL;107. constchar*msg=NULL;108. 109. if(msgObj=NULL)110. jclassnpeClazz;111. 112. npeClazz=env-FindClass(java/lang/NullPointerException);113. assert(npeClazz!=NULL);114. 115. env-ThrowNew(npeClazz,printlnneedsamessage);116. return-1;117. 118. 119. if(bufID=LOG_ID_MAX)120. jclassnpeClazz;121. 122. npeClazz=env-FindClass(java/lang/NullPointerException);123. assert(npeClazz!=NULL);124. 125. env-ThrowNew(npeClazz,badbufID);126. return-1;127. 128. 129. if(tagObj!=NULL)130. tag=env-GetStringUTFChars(tagObj,NULL);131. msg=env-GetStringUTFChars(msgObj,NULL);132. 133. intres=_android_log_buf_write(bufID,(android_LogPriority)priority,tag,msg);134. 135. if(tag!=NULL)136. env-ReleaseStringUTFChars(tagObj,tag);137. env-ReleaseStringUTFChars(msgObj,msg);138. 139. returnres;140. 141. 142. /*143. *JNIregistration.144. */145. staticJNINativeMethodgMethods=146. /*name,signature,funcPtr*/147. isLoggable,(Ljava/lang/String;I)Z,(void*)android_util_Log_isLoggable,148. println_native,(IILjava/lang/String;Ljava/lang/String;)I,(void*)android_util_Log_println_native,149. ;150. 151. intregister_android_util_Log(JNIEnv*env)152. 153. jclassclazz=env-FindClass(android/util/Log);154. 155. if(clazz=NULL)156. LOGE(Cantfindandroid/util/Log);157. return-1;158. 159. 160. levels.verbose=env-GetStaticIntField(clazz,env-GetStaticFieldID(clazz,VERBOSE,I);161. levels.debug=env-GetStaticIntField(clazz,env-GetStaticFieldID(clazz,DEBUG,I);162. =env-GetStaticIntField(clazz,env-GetStaticFieldID(clazz,INFO,I);163. levels.warn=env-GetStaticIntField(clazz,env-GetStaticFieldID(clazz,WARN,I);164. levels.error=env-GetStaticIntField(clazz,env-GetStaticFieldID(clazz,ERROR,I);165. levels.assert=env-GetStaticIntField(clazz,env-GetStaticFieldID(clazz,ASSERT,I);166. 167. returnAndroidRuntime:registerNativeMethods(env,android/util/Log,gMethods,NELEM(gMethods);168. 169. 170. ;/namespaceandroid 在gMethods变量中,定义了println_native本地方法对应的函数调用是android_util_Log_println_native。在android_util_Log_println_native函数中,通过了各项参数验证正确后,就调用运行时库函数_android_log_buf_write来实现Log的写入操作。_android_log_buf_write函实实现在liblog库中,它有4个参数,分别缓冲区ID、优先级别ID、Tag字符串和Msg字符串。下面运行时库liblog中的_android_log_buf_write的实现。 三.系统运行库层日志系统的实现。 在系统运行库层liblog库的实现中,内容比较多,这里,我们只关注日志写入操作_android_log_buf_write的相关实现:view plain1. int_android_log_buf_write(intbufID,intprio,constchar*tag,constchar*msg)2. 3. structiovecvec3;4. 5. if(!tag)6. tag=;7. 8. /*XXX:Thisneedstogo!*/9. if(!strcmp(tag,HTC_RIL)|10. !strncmp(tag,RIL,3)|/*AnylogtagwithRILastheprefix*/11. !strcmp(tag,AT)|12. !strcmp(tag,GSM)|13. !strcmp(tag,STK)|14. !strcmp(tag,CDMA)|15. !strcmp(tag,PHONE)|16. !strcmp(tag,SMS)17. bufID=LOG_ID_RADIO;18. 19. vec0.iov_base=(unsignedchar*)&prio;20. vec0.iov_len=1;21. vec1.iov_base=(void*)tag;22. vec1.iov_len=strlen(tag)+1;23. vec2.iov_base=(void*)msg;24. vec2.iov_len=strlen(msg)+1;25. 26. returnwrite_to_log(bufID,vec,3);27. 函数首先是检查传进来的tag参数是否是为HTC_RIL、RIL、AT、GSM、STK、CDMA、PHONE和SMS中的一个,如果是,就无条件地使用ID为LOG_ID_RADIO的日志缓冲区作为写入缓冲区,接着,把传进来的参数prio、tag和msg分别存放在一个向量数组中,调用write_to_log函数来进入下一步操作。write_to_log是一个函数指针,定义在文件开始的位置上:view plain1. staticint_write_to_log_init(log_id_t,structiovec*vec,size_tnr);2. staticint(*write_to_log)(log_id_t,structiovec*vec,size_tnr)=_write_to_log_init; 并且初始化为_write_to_log_init函数:view plain1. staticint_write_to_log_init(log_id_tlog_id,structiovec*vec,size_tnr)2. 3. #ifdefHAVE_PTHREADS4. pthread_mutex_lock(&log_init_lock);5. #endif6. 7. if(write_to_log=_write_to_log_init)8. log_fdsLOG_ID_MAIN=log_open(/dev/LOGGER_LOG_MAIN,O_WRONLY);9. log_fdsLOG_ID_RADIO=log_open(/dev/LOGGER_LOG_RADIO,O_WRONLY);10. log_fdsLOG_ID_EVENTS=log_open(/dev/LOGGER_LOG_EVENTS,O_WRONLY);11. log_fdsLOG_ID_SYSTEM=log_open(/dev/LOGGER_LOG_SYSTEM,O_WRONLY);12. 13. write_to_log=_write_to_log_kernel;14. 15. if(log_fdsLOG_ID_MAIN0|log_fdsLOG_ID_RADIO0|16. log_fdsLOG_ID_EVENTS0)17. log_close(log_fdsLOG_ID_MAIN);18. log_close(log_fdsLOG_ID_RADIO);19. log_close(log_fdsLOG_ID_EVENTS);20. log_fdsLOG_ID_MAIN=-1;21. log_fdsLOG_ID_RADIO=-1;22. log_fdsLOG_ID_EVENTS=-1;23. write_to_log=_write_to_log_null;24. 25. 26. if(log_fdsLOG_ID_SYSTEM0)27. log_fdsLOG_ID_SYSTEM=log_fdsLOG_ID_MAIN;28. 29. 30. 31. #ifdefHAVE_PTHREADS32. pthread_mutex_unlock(&log_init_lock);33. #endif34. 35. returnwrite_to_log(log_id,vec,nr);36. 这里我们可以看到,如果是第一次调write_to_log函数,write
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 桥台及台身施工方案设计
- 大山里的施工方案设计
- 钢架房屋配送方案范本
- 2025年职高专业信息题库及答案
- 农林管理方案范本
- 山东济南市商河县城乡公益性岗位招聘考试真题2024
- 监理施工方案的审批权限
- 钢结构管线架空施工方案
- 瑞安地源热泵井施工方案
- 雾化系统检修方案范本
- 2025中国电建成都院勘测设计分公司社会招聘笔试历年参考题库附带答案详解
- 精神科护理科普:理解与关爱慢性精神疾病患者
- 再生障碍性贫血护理教学查房
- 法律与道德小学生课件
- vivo公司管理制度
- 2025自考专业(国贸)考前冲刺试卷及完整答案详解
- DB31/T 804-2014生活饮用水卫生管理规范
- 儿童早期矫正教学课件
- 银行代销业务管理制度
- 运动素质知到课后答案智慧树章节测试答案2025年春浙江大学
- 招聘话术培训
评论
0/150
提交评论