概述

Framework开发是一项非常繁琐复杂的工作,需要阅读大量的源代码,分析及其多的LOG信息来定位错误位置。这个时候如果使用一些工具或者知道如何定位重要LOG信息,就可以使一些复杂的工作变的简单很多,使我们分析问题的效率变得更快,不再为阅读大量的源代码而感到一筹莫展。本文将针对一些场景讲解如何分析系统LOG信息,如何添加LOG定位错误信息,以及常用工具以及使用方法。

常用工具

HierarchyViewer

HierarchyViewer是随Android SDK发布的工具,位置在sdktools文件夹下,名为hierarchyviewer。它是Android自带的非常有用而且使用简单的工具,能够让我们从可视化的角度直观地获得UI布局设计结构和各种属性的信息,帮助我们优化布局设计。打开HierarchyViewer后我们可以看到当前view的布局,如下图所示。

DDMS

DDMS 的全称是Dalvik Debug Monitor Service,是Android开发环境中的Dalvik虚拟机调试监控服务。它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息、Logcat、广播状态信息、模拟电话呼叫、接收SMS、虚拟地理坐标等等。DDMS打开界面如下:

左侧的Devices一栏会列出已连接的设备,点击设备名称左侧三角符号图标会列出该设备运行中的进程的app包名。

模拟按键

使用命令adb shell input keyevent + 对应的键值,可以模拟对应的操作。手机系统中主要的键值如下:

[java] view plaincopy

  1. /** Key code constant: Home key.
  2. * This key is handled by the framework and is never delivered to applications. */
  3. publicstaticfinalintKEYCODE_HOME            =3;//Home键
  4. /** Key code constant: Back key. */
  5. publicstaticfinalintKEYCODE_BACK            =4;//Back键
  6. /** Key code constant: Call key. */
  7. publicstaticfinalintKEYCODE_CALL            =5;//打电话
  8. /** Key code constant: End Call key. */
  9. publicstaticfinalintKEYCODE_ENDCALL         =6;//挂断电话
  10. /** Key code constant: Volume Up key.
  11. * Adjusts the speaker volume up. */
  12. publicstaticfinalintKEYCODE_VOLUME_UP       =24;//调大声音
  13. /** Key code constant: Volume Down key.
  14. * Adjusts the speaker volume down. */
  15. publicstaticfinalintKEYCODE_VOLUME_DOWN     =25;//调小声音
  16. /** Key code constant: Power key. */
  17. publicstaticfinalintKEYCODE_POWER           =26;//电源键
  18. /** Key code constant: Camera key.
  19. * Used to launch a camera application or take pictures. */
  20. publicstaticfinalintKEYCODE_CAMERA          =27;//相机按键
  21. /** Key code constant: Clear key. */
  22. publicstaticfinalintKEYCODE_CLEAR           =28;//清理
  23. /** Key code constant: Space key. */
  24. publicstaticfinalintKEYCODE_SPACE           =62;//空格键
  25. /** Key code constant: Backspace key.
  26. * Deletes characters before the insertion point, unlike {@link #KEYCODE_FORWARD_DEL}. */
  27. publicstaticfinalintKEYCODE_DEL             =67;//删除键
  28. /** Key code constant: Menu key. */
  29. publicstaticfinalintKEYCODE_MENU            =82;//菜单键

当我们要模拟power键亮灭屏事件就可以执行下面命令:

[java] view plaincopy

  1. adb shell input keyevent26

模拟别的按键事件同理。

而adb shell getevent / adb shell sendevent是发送对应的事件,包括触屏,按键等事件。

am命令

有时候我们在调试系统时可以在终端使用am命令来发送广播,打开Activity,启动Service等操作,十分方便。am的详细操作如下,我们可以通过adb shell am + 对应命令,就可操作。

[java] view plaincopy

  1. usage: am [subcommand] [options]
  2. usage: am start [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]
  3. [--sampling INTERVAL] [-R COUNT] [-S]
  4. [--track-allocation] [--user <USER_ID> | current] <INTENT> //可以通过该命令启动对应Activity
  5. am startservice [--user <USER_ID> | current] <INTENT>   //启动服务
  6. am stopservice [--user <USER_ID> | current] <INTENT>    //停止服务
  7. am force-stop [--user <USER_ID> | all | current] <PACKAGE>  //通过包名强制停止应用
  8. am kill [--user <USER_ID> | all | current] <PACKAGE>  //根据进程号杀死进程
  9. am kill-all                                           //杀掉所有后台进程
  10. am broadcast [--user <USER_ID> | all | current] <INTENT>  //发送广播
  11. am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]
  12. [--user <USER_ID> | current]
  13. [--no-window-animation] [--abi <ABI>] <COMPONENT>
  14. am profile start [--user <USER_ID> current] [--sampling INTERVAL] <PROCESS> <FILE> //抓取traceview
  15. am profile stop [--user <USER_ID> current] [<PROCESS>]      //停止抓取traceview
  16. am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>
  17. am set-debug-app [-w] [--persistent] <PACKAGE>
  18. am clear-debug-app
  19. am set-watch-heap <PROCESS> <MEM-LIMIT>
  20. am clear-watch-heap
  21. am bug-report [--progress]
  22. am monitor [--gdb <port>]
  23. am hang [--allow-restart]
  24. am restart                             //重启应用
  25. am idle-maintenance
  26. am screen-compat [on|off] <PACKAGE>
  27. am package-importance <PACKAGE>
  28. am to-uri [INTENT]
  29. am to-intent-uri [INTENT]
  30. am to-app-uri [INTENT]
  31. am switch-user <USER_ID>
  32. am start-user <USER_ID>
  33. am unlock-user <USER_ID> [TOKEN_HEX]
  34. am stop-user [-w] [-f] <USER_ID>
  35. am stack start <DISPLAY_ID> <INTENT>
  36. am stack movetask <TASK_ID> <STACK_ID> [true|false]//stack相关
  37. am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
  38. am stack resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
  39. am stack resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]
  40. am stack size-docked-stack-test: <STEP_SIZE> <l|t|r|b> [DELAY_MS]
  41. am stack move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
  42. am stack positiontask <TASK_ID> <STACK_ID> <POSITION>
  43. am stack list                                    //列出系统中的所有stack
  44. am stack info <STACK_ID>                         //stack信息
  45. am stack remove <STACK_ID>                       //移除stack
  46. am task lock <TASK_ID>
  47. am task lock stop
  48. am task resizeable <TASK_ID> [0(unresizeable) |1(crop_windows) |2(resizeable) |3(resizeable_and_pipable)]
  49. am task resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>
  50. am task drag-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]
  51. am task size-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]
  52. am get-config
  53. am suppress-resize-config-changes <true|false>
  54. am set-inactive [--user <USER_ID>] <PACKAGE> true|false
  55. am get-inactive [--user <USER_ID>] <PACKAGE>
  56. am send-trim-memory [--user <USER_ID>] <PROCESS>
  57. [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]
  58. am get-current-user
  59. am start: start an Activity.  Options are:    //启动Activity详细使用方法
  60. -D: enable debugging
  61. -N: enable nativedebugging
  62. -W: wait forlaunch to complete
  63. --start-profiler <FILE>: start profiler and send results to <FILE>
  64. --sampling INTERVAL: use sample profiling with INTERVAL microseconds
  65. between samples (use with --start-profiler)
  66. -P <FILE>: like above, but profiling stops when app goes idle
  67. -R: repeat the activity launch <COUNT> times.  Prior to each repeat,
  68. the top activity will be finished.
  69. -S: force stop the target app before starting the activity
  70. --track-allocation: enable tracking of object allocations
  71. --user <USER_ID> | current: Specify which user to run as; ifnot
  72. specified then run as the current user.
  73. --stack <STACK_ID>: Specify into which stack should the activity be put.
  74. am startservice: start a Service.  Options are:
  75. --user <USER_ID> | current: Specify which user to run as; ifnot
  76. specified then run as the current user.
  77. am stopservice: stop a Service.  Options are:
  78. --user <USER_ID> | current: Specify which user to run as; ifnot
  79. specified then run as the current user.
  80. am force-stop: force stop everything associated with <PACKAGE>.
  81. --user <USER_ID> | all | current: Specify user to force stop;
  82. all users ifnot specified.
  83. am kill: Kill all processes associated with <PACKAGE>.  Only kills.
  84. processes that are safe to kill -- that is, will not impact the user
  85. experience.
  86. --user <USER_ID> | all | current: Specify user whose processes to kill;
  87. all users ifnot specified.
  88. am kill-all: Kill all background processes.
  89. am broadcast: send a broadcast Intent.  Options are:
  90. --user <USER_ID> | all | current: Specify which user to send to; ifnot
  91. specified then send to all users.
  92. --receiver-permission <PERMISSION>: Require receiver to hold permission.
  93. am instrument: start an Instrumentation.  Typically thistarget <COMPONENT>
  94. is the form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> ifthere
  95. is only one instrumentation.  Options are:
  96. -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT).  Use with
  97. [-e perf true] to generate raw outputforperformance measurements.
  98. -e <NAME> <VALUE>: set argument <NAME> to <VALUE>.  For test runners a
  99. common form is [-e <testrunner_flag> <value>[,<value>...]].
  100. -p <FILE>: write profiling data to <FILE>
  101. -w: wait forinstrumentation to finish before returning.  Requiredfor
  102. test runners.
  103. --user <USER_ID> | current: Specify user instrumentation runs in;
  104. current user ifnot specified.
  105. --no-window-animation: turn off window animations whilerunning.
  106. --abi <ABI>: Launch the instrumented process with the selected ABI.
  107. This assumes that the process supports the selected ABI.
  108. am trace-ipc: Trace IPC transactions.
  109. start: start tracing IPC transactions.
  110. stop: stop tracing IPC transactions and dump the results to file.
  111. --dump-file <FILE>: Specify the file the trace should be dumped to.
  112. am profile: start and stop profiler on a process.  The given <PROCESS> argument
  113. may be either a process name or pid.  Options are:
  114. --user <USER_ID> | current: When supplying a process name,
  115. specify user of process to profile; uses current user ifnot specified.
  116. am dumpheap: dump the heap of a process.  The given <PROCESS> argument may
  117. be either a process name or pid.  Options are:
  118. -n: dump nativeheap instead of managed heap
  119. --user <USER_ID> | current: When supplying a process name,
  120. specify user of process to dump; uses current user ifnot specified.
  121. am set-debug-app: set application <PACKAGE> to debug.  Options are:
  122. -w: wait fordebugger when application starts
  123. --persistent: retain thisvalue
  124. am clear-debug-app: clear the previously set-debug-app.
  125. am set-watch-heap: start monitoring pss size of <PROCESS>, ifit is at or
  126. above <HEAP-LIMIT> then a heap dump is collected forthe user to report
  127. am clear-watch-heap: clear the previously set-watch-heap.
  128. am bug-report: request bug report generation; will launch a notification
  129. when done to select where it should be delivered. Options are:
  130. --progress: will launch a notification right away to show its progress.
  131. am monitor: start monitoring forcrashes or ANRs.
  132. --gdb: start gdbserv on the given port at crash/ANR
  133. am hang: hang the system.
  134. --allow-restart: allow watchdog to perform normal system restart
  135. am restart: restart the user-space system.
  136. am idle-maintenance: perform idle maintenance now.
  137. am screen-compat: control screen compatibility mode of <PACKAGE>.
  138. am package-importance: print current importance of <PACKAGE>.
  139. am to-uri: print the given Intent specification as a URI.
  140. am to-intent-uri: print the given Intent specification as an intent: URI.
  141. am to-app-uri: print the given Intent specification as an android-app: URI.
  142. am switch-user:switchto put USER_ID in the foreground, starting
  143. execution of that user ifit is currently stopped.
  144. am start-user: start USER_ID in background ifit is currently stopped,
  145. use switch-userifyou want to start the user in foreground.
  146. am stop-user: stop execution of USER_ID, not allowing it to run any
  147. code until a later explicit start or switchto it.
  148. -w: wait forstop-user to complete.
  149. -f: force stop even ifthere are related users that cannot be stopped.
  150. am stack start: start a newactivity on <DISPLAY_ID> using <INTENT>.
  151. am stack movetask: move <TASK_ID> from its current stack to the top (true) or   bottom (false) of <STACK_ID>.
  152. am stack resize: change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.
  153. am stack resize-docked-stack: change docked stack to <LEFT,TOP,RIGHT,BOTTOM>
  154. and supplying temporary different task bounds indicated by
  155. <TASK_LEFT,TOP,RIGHT,BOTTOM>
  156. am stack size-docked-stack-test: test command forsizing docked stack by
  157. <STEP_SIZE> increments from the side <l>eft, <t>op, <r>ight, or <b>ottom
  158. applying the optional [DELAY_MS] between each step.
  159. am stack move-top-activity-to-pinned-stack: moves the top activity from
  160. <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> forthe
  161. bounds of the pinned stack.
  162. am stack positiontask: place <TASK_ID> in <STACK_ID> at <POSITION>
  163. am stack list: list all of the activity stacks and their sizes.
  164. am stack info: display the information about activity stack <STACK_ID>.
  165. am stack remove: remove stack <STACK_ID>.
  166. am task lock: bring <TASK_ID> to the front and don't allow other tasks to run.
  167. am task lock stop: end the current task lock.
  168. am task resizeable: change resizeable mode of <TASK_ID>.
  169. 0(unresizeable) |1(crop_windows) |2(resizeable) |3(resizeable_and_pipable)
  170. am task resize: makes sure <TASK_ID> is in a stack with the specified bounds.
  171. Forces the task to be resizeable and creates a stack ifno existing stack
  172. has the specified bounds.
  173. am task drag-task-test: test command fordragging/moving <TASK_ID> by
  174. <STEP_SIZE> increments around the screen applying the optional [DELAY_MS]
  175. between each step.
  176. am task size-task-test: test command forsizing <TASK_ID> by <STEP_SIZE>   increments within the screen applying the optional [DELAY_MS] between
  177. each step.
  178. am get-config: retrieve the configuration and any recent configurations
  179. of the device.
  180. am suppress-resize-config-changes: suppresses configuration changes due to
  181. user resizing an activity/task.
  182. am set-inactive: sets the inactive state of an app.
  183. am get-inactive: returns the inactive state of an app.
  184. am send-trim-memory: send a memory trim event to a <PROCESS>.
  185. am get-current-user: returns id of the current foreground user.
  186. <INTENT> specifications include these flags and arguments:
  187. [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
  188. [-c <CATEGORY> [-c <CATEGORY>] ...]
  189. [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
  190. [--esn <EXTRA_KEY> ...]
  191. [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
  192. [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
  193. [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]
  194. [--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]
  195. [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]
  196. [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]
  197. [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]
  198. (mutiple extras passed as Integer[])
  199. [--eial <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]
  200. (mutiple extras passed as List<Integer>)
  201. [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]
  202. (mutiple extras passed as Long[])
  203. [--elal <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]
  204. (mutiple extras passed as List<Long>)
  205. [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]
  206. (mutiple extras passed as Float[])
  207. [--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]
  208. (mutiple extras passed as List<Float>)
  209. [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
  210. (mutiple extras passed as String[]; to embed a comma into a string,
  211. escape it using "\,")
  212. [--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
  213. (mutiple extras passed as List<String>; to embed a comma into a string,
  214. escape it using "\,")
  215. [--f <FLAG>]
  216. [--grant-read-uri-permission] [--grant-write-uri-permission]
  217. [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]
  218. [--debug-log-resolution] [--exclude-stopped-packages]
  219. [--include-stopped-packages]
  220. [--activity-brought-to-front] [--activity-clear-top]
  221. [--activity-clear-when-task-reset] [--activity-exclude-from-recents]
  222. [--activity-launched-from-history] [--activity-multiple-task]
  223. [--activity-no-animation] [--activity-no-history]
  224. [--activity-no-user-action] [--activity-previous-is-top]
  225. [--activity-reorder-to-front] [--activity-reset-task-if-needed]
  226. [--activity-single-top] [--activity-clear-task]
  227. [--activity-task-on-home]
  228. [--receiver-registered-only] [--receiver-replace-pending]
  229. [--receiver-foreground]
  230. [--selector]
  231. [<URI> | <PACKAGE> | <COMPONENT>]

pm命令

当要查询系统中某个应用是否存在,或者存在路径,就可以根据对应的包名来查找对应的apk信息。

[java] view plaincopy

  1. usage: pm path [--user USER_ID] PACKAGE
  2. pm dump PACKAGE                       //dump某个apk
  3. pm install [-lrtsfd] [-i PACKAGE] [--user USER_ID] [PATH]  //安装应用
  4. pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]
  5. [--install-location 0/1/2]
  6. [--force-uuid internal|UUID]
  7. pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]
  8. pm install-commit SESSION_ID
  9. pm install-abandon SESSION_ID
  10. pm uninstall [-k] [--user USER_ID] PACKAGE            //卸载应用
  11. pm set-installer PACKAGE INSTALLER                    //设置installer
  12. pm move-packagePACKAGE [internal|UUID]//移除package
  13. pm move-primary-storage [internal|UUID]
  14. pm clear [--user USER_ID] PACKAGE                     //清除应用信息
  15. pm enable [--user USER_ID] PACKAGE_OR_COMPONENT
  16. pm disable [--user USER_ID] PACKAGE_OR_COMPONENT
  17. pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT
  18. pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT
  19. pm default-state [--user USER_ID] PACKAGE_OR_COMPONENT
  20. pm hide [--user USER_ID] PACKAGE_OR_COMPONENT
  21. pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT
  22. pm grant [--user USER_ID] PACKAGE PERMISSION
  23. pm revoke [--user USER_ID] PACKAGE PERMISSION
  24. pm reset-permissions                                //重置权限
  25. pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}
  26. pm get-app-link [--user USER_ID] PACKAGE
  27. pm set-install-location [0/auto] [1/internal] [2/external]//设置安装路径
  28. pm get-install-location                                     获取安装路径
  29. pm set-permission-enforced PERMISSION [true|false]
  30. pm trim-caches DESIRED_FREE_SPACE [internal|UUID]
  31. pm create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral] [--guest] USER_NAME
  32. pm remove-user USER_ID
  33. pm get-max-users
  34. NOTE: 'pm list'commands have moved! Run'adb shell cmd package'
  35. to display the newcommands.//使用adb shell pm list packages -f获取系统中所有apk的安装路径
  36. pm path: print the path to the .apk of the given PACKAGE. //adb shell path +包名,获取apk路径
  37. pm dump: print system state associated with the given PACKAGE.
  38. pm install: install a single legacy package
  39. pm install-create: create an install session
  40. -l: forward lock application
  41. -r: replace existing application
  42. -t: allow test packages
  43. -i: specify the installer packagename
  44. -s: install application on sdcard
  45. -f: install application on internal flash
  46. -d: allow version code downgrade (debuggable packages only)
  47. -p: partial application install
  48. -g: grant all runtime permissions
  49. -S: size in bytes of entire session
  50. pm install-write: write a packageinto existing session; path may
  51. be '-'to read from stdin
  52. -S: size in bytes of package, requiredforstdin
  53. pm install-commit: perform install of fully staged session
  54. pm install-abandon: abandon session
  55. pm set-installer: set installer packagename
  56. pm uninstall: removes a packagefrom the system. Options:
  57. -k: keep the data and cache directories around after packageremoval.
  58. pm clear: deletes all data associated with a package.
  59. pm enable, disable, disable-user, disable-until-used, default-state:
  60. these commands change the enabled state of a given packageor
  61. component (written as "package/class").
  62. pm grant, revoke: these commands either grant or revoke permissions
  63. to apps. The permissions must be declared as used in the app's
  64. manifest, be runtime permissions (protection level dangerous),
  65. and the app targeting SDK greater than Lollipop MR1.
  66. pm reset-permissions: revert all runtime permissions to their defaultstate.
  67. pm get-install-location: returns the current install location.
  68. 0[auto]: Let system decide the best location
  69. 1[internal]: Install on internal device storage
  70. 2[external]: Install on external media
  71. pm set-install-location: changes the defaultinstall location.
  72. NOTE: thisis only intendedfordebugging; usingthiscan cause
  73. applications to breakand other undersireable behavior.
  74. 0[auto]: Let system decide the best location
  75. 1[internal]: Install on internal device storage
  76. 2[external]: Install on external media
  77. pm trim-caches: trim cache files to reach the given free space.
  78. pm create-user: create a newuser with the given USER_NAME,
  79. printing the newuser identifier of the user.
  80. pm remove-user: remove the user with the given USER_IDENTIFIER,
  81. deleting all data associated with that user

dumpsys

该命令用于打印出当前系统信息,默认打印出设备中所有service的信息,可以在命令后面加指定的service name

可以通过adb shell dumpsys + services可以打印出对应系统service的dump信息。可以将某个模块详细信息输出到控制台,可以更加直观的分析。

例如要打印Activity的dump信息:adb shell dumpsys activity

[java] view plaincopy

  1. Currently running services:
  2. AtCmdFwd
  3. DockObserver
  4. SurfaceFlinger     //重要
  5. accessibility
  6. account
  7. activity          //重要
  8. alarm             //重要
  9. android.security.keystore
  10. android.service.gatekeeper.IGateKeeperService
  11. appops
  12. appwidget
  13. assetatlas
  14. audio           //重要
  15. backup
  16. battery         //重要
  17. batteryproperties
  18. batterystats
  19. bluetooth_manager
  20. carrier_config
  21. clipboard
  22. cneservice
  23. com.qualcomm.location.izat.IzatService
  24. com.qualcomm.qti.qseeproxy
  25. commontime_management
  26. connectivity
  27. connectivity_metrics_logger
  28. connmetrics
  29. consumer_ir
  30. content
  31. contexthub_service
  32. country_detector
  33. cpuinfo
  34. dbinfo
  35. device_policy
  36. deviceidle
  37. devicestoragemonitor
  38. diskstats
  39. display       //重要
  40. display.qservice
  41. dpmservice
  42. dreams
  43. drm.drmManager
  44. dropbox
  45. eSEPowerManagerService
  46. ethernet
  47. extphone
  48. gfxinfo
  49. gpu         //重要
  50. graphicsstats
  51. hardware_properties
  52. imms
  53. ims
  54. input       //重要
  55. input_method  //重要
  56. iphonesubinfo
  57. isms
  58. isub
  59. jobscheduler
  60. launcherapps
  61. location
  62. lock_settings
  63. mdtp
  64. media.audio_flinger
  65. media.audio_policy
  66. media.camera
  67. media.camera.proxy
  68. media.codec
  69. media.drm
  70. media.extractor
  71. media.player
  72. media.radio
  73. media.resource_manager
  74. media.sound_trigger_hw
  75. media_projection
  76. media_router
  77. media_session
  78. meminfo       //输出内存相关,重要
  79. midi
  80. mount
  81. netd
  82. netd_listener
  83. netpolicy
  84. netstats
  85. network_management
  86. network_score
  87. network_time_update_service
  88. notification
  89. okay_property
  90. otadexopt
  91. package//重要
  92. permission
  93. persistent_data_block
  94. phone
  95. pinner
  96. power           //电源管理,重要
  97. print
  98. processinfo
  99. procstats
  100. qti.ims.connectionmanagerservice
  101. qti.ims.ext
  102. qtitetherservice
  103. recovery
  104. regionalization
  105. restrictions
  106. rttmanager
  107. samplingprofiler
  108. scheduling_policy
  109. search
  110. sensorservice
  111. serial
  112. servicediscovery
  113. shortcut
  114. simphonebook
  115. soundtrigger
  116. statusbar
  117. telecom
  118. telephony.registry
  119. textservices
  120. trust
  121. uimode
  122. updatelock
  123. usagestats
  124. usb
  125. user
  126. vendor.qcom.PeripheralManager
  127. vibrator
  128. voiceinteraction
  129. vrmanager
  130. wallpaper     //重要
  131. webviewupdate
  132. wifi
  133. wifip2p
  134. wifiscanner
  135. window         //Windows管理信息,重要

wakelock

wakelock主要是系统为上层提供控制屏幕亮度显示,以及cpu唤醒的一个接口。我们可以通过上面学习的dumpsys命令来查看系统此时存在那些wakelock。

adb shell dumpsys power

[java] view plaincopy

  1. Wake Locks: size=1
  2. SCREEN_BRIGHT_WAKE_LOCK        'WindowManager'ON_AFTER_RELEASE ACQ=-1s234ms (uid=1000pid=1495ws=WorkSource{1000})

此时系统只有一个wakelock,类型为SCREEN_BRIGHT_WAKE_LOCK,所属模块为WIndowManager。下面讲解一下如何使用wakelock。

[java] view plaincopy

  1. PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);//获取PowerManager
  2. sWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK   //使用power创建一个新的wakelock,执行类型
  3. | PowerManager.ACQUIRE_CAUSES_WAKEUP
  4. | PowerManager.ON_AFTER_RELEASE, TAG);
  5. sWakeLock.acquire();                                    //使wakelock起作用,当不需要时使用release释放wakelock

任何应用程序使用WakeLock,必须要求android.permission.WAKE_LOCK许可在应用程序的清单上使用<uses-permission>元素。下面为我们可以调用的公共方法。

[java] view plaincopy

  1. Public Methods
  2. voidacquire() --->当你创建这个WakeLock时,确保这个设备按照你的要求保持唤醒的状态。
  3. voidacquire(longtimeout) --->当你创建这个WakeLock时,确保这个设备按照你的要求保持唤醒的状态。
  4. voidisHeld()
  5. voidrelease() ---> 按照你的要求释放cpu或屏幕。
  6. voidsetReferenceCounted(booleanvalue)--->如果需要使用引用计数,则将value设置为true。默认设置为true,表示当用户申请多少次锁时,就必须释放多少次。
  7. voidsetWorkSource(WorkSource ws)
  8. String toString() --->返回一个简洁的字符串用来将这个对象描述为人们可读懂的。
  9. voidFinalize() --->当垃圾收集器检测到该实例不再运行调用。

wakelock有不同的类型,我们可以根据需要选择不同的wakelock类型。

Flag Value CPU Screen Keyboard
PARTIAL_WAKE_LOCK On Off   Off
SCREEN_DIM_WAKE_LOCK On  Dim Off
SCREEN_BRIGHT_WAKE_LOCK On Bright Off
FULL_WAKE_LOCK On Bright Bright
如果你持有的partial wakelock,CPU将继续运行,不论何时,即使当用户按下电源按钮。对于所有其他wakelocks,但用户使用电源按钮时,系统将进入睡眠,cpu将不再继续运行。
PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。
SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯
SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯
FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
ACQUIRE_CAUSES_WAKEUP:正常唤醒锁实际上并不打开照明。相反,一旦打开他们会一直仍然保持(例如来世user的activity)。当获得wakelock,这个标志会使屏幕或/和键盘立即打开。一个典型的使用就是可以立即看到那些对用户重要的通知。
ON_AFTER_RELEASE:设置了这个标志,当wakelock释放时用户activity计时器会被重置,导致照明持续一段时间。如果你在wacklock条件中循环,这个可以用来减少闪烁
我们可以创建多个锁,并hold它,即使对同一类型,也如此,对于某类型的wakelock只要有一个被hold,那么它所对应的电源状态(illumination),就将不会超时,将被延续(hold).在上表中我们把越往下的,称为更高一级的wakelocks.当高级和低级wakelocks相遇的时候,高级起作用。在上面的flag上还再加上如下的2个flag,但是他们和PARTIAL_WAKE_LOCK.组合没任何意义ACQUIRE_CAUSES_WAKEUP默认情况下wake locks并不是马上开启CPU或Screen或Keyboard的(对于Screen是Dim或Bright,Keyboard是Bright. wake locks只是在被开启后(比如用户的活动),让设备延续(保存)你设定开启的状态. 但是如果加上ACQUIRE_CAUSES_WAKEUP就可以让Screen或Keyboar没开启的情况,马上开启它们。 典型的应用就是在收到一个重要的notifications时,需要马上点亮屏幕。

addr2line

在分析framework稳定性问题时会遇到Native crash的发生,而Native crash与java crash的堆栈信息不同。下面是一段Native 堆栈的片段。

[java] view plaincopy

  1. 03-1914:58:50.0343193145D kevin_Render: #01pc 0005f8a5  /system/lib/libmediaplayerservice.so (android::NuPlayer::Renderer::setAnchorTime(longlong,longlong,longlong, bool)+72)
  2. 03-1914:58:50.0343193145D kevin_Render: #02pc 000618c5  /system/lib/libmediaplayerservice.so (android::NuPlayer::Renderer::onNewAudioMediaTime(longlong)+88)
  3. 03-1914:58:50.0353193145D kevin_Render: #03pc00062249/system/lib/libmediaplayerservice.so (android::NuPlayer::Renderer::onDrainAudioQueue()+764)
  4. 03-1914:58:50.0353193145D kevin_Render: #04pc 00062ec3  /system/lib/libmediaplayerservice.so (android::NuPlayer::Renderer::onMessageReceived(android::sp<android::AMessage>const&)+866)
  5. 03-1914:58:50.0353193145D kevin_Render: #05pc 0000d12d  /system/lib/libstagefright_foundation.so (android::ALooperRoster::deliverMessage(android::sp<android::AMessage>const&)+164)
  6. 03-1914:58:50.0353193145D kevin_Render: #06pc 0000cac1  /system/lib/libstagefright_foundation.so (android::ALooper::loop()+216)
  7. 03-1914:58:50.0353193145D kevin_Render: #07pc00010977/system/lib/libutils.so (android::Thread::_threadLoop(void*)+110)
  8. 03-1914:58:50.0353193145D kevin_Render: #08pc 00016f5b  /system/lib/libc.so (__pthread_start(void*)+30)
  9. 03-1914:58:50.0353193145D kevin_Render: #09pc 00014f7b  /system/lib/libc.so (__start_thread+6)

根据上面的堆栈,我们并不能看到具体哪个函数,哪行代码出现了问题,这个时候我们就需要解析Native函数的地址值,如上面 00062ec3这样的符号,我们需要通过addr2line来进行解析。我们可以使用linux系统提供的addr2line命令,也可以使用源代码sdk中的工具。具体命令如下:

addr2line -e out/target/product/项目名/symbols/system/lib/libxxx.so -f -C <addr> 
如果我们想要解析03行的地址值00062249
[java] view plaincopy

  1. kevin@kevin-All-Series:~/work/$ addr2line -e out/target/product/miki8163_9003/symbols/system/lib/libmediaplayerservice.so -f -C00062249
  2. android::NuPlayer::Renderer::onDrainAudioQueue()
  3. /home/kevin/work/source/sm8163/sm8163/frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp:868

解析后我们看到该行代码属于函数android::NuPlayer::Renderer::onDrainAudioQueue(),在NuPlayerRenderer.cpp的868行,这样就十分方便了。

meminfo

当我们查询系统的内存信息除了使用dumpsys命令,还可以直接使用adb shell cat /proc/meminfo

[java] view plaincopy

  1. kevin@kevin-All-Series:~/work$ adb shell cat /proc/meminfo
  2. MemTotal:        1844152kB//内存的总大小
  3. MemFree:           41364kB//空闲内存
  4. MemAvailable:     230892kB//可用的内存
  5. Buffers:            3520kB
  6. Cached:           230312kB//缓存
  7. SwapCached:         6484kB
  8. Active:           538568kB
  9. Inactive:         257680kB
  10. Active(anon):     426264kB
  11. Inactive(anon):   144884kB
  12. Active(file):     112304kB
  13. Inactive(file):   112796kB
  14. Unevictable:         256kB
  15. Mlocked:             256kB
  16. SwapTotal:        524284kB
  17. SwapFree:            156kB
  18. Dirty:                44kB//脏页
  19. Writeback:             0kB
  20. AnonPages:        559864kB
  21. Mapped:           216980kB
  22. Shmem:              8608kB
  23. Slab:             354744kB
  24. SReclaimable:      56820kB
  25. SUnreclaim:       297924kB
  26. KernelStack:       35488kB
  27. PageTables:        34172kB
  28. NFS_Unstable:          0kB
  29. Bounce:                0kB
  30. WritebackTmp:          0kB
  31. CommitLimit:     1446360kB
  32. Committed_AS:   63267272kB
  33. VmallocTotal:   244318144kB
  34. VmallocUsed:      116780kB
  35. VmallocChunk:   244056036kB

fastboot

Android系统编译后会生成很多的image文件,我们可以通过刷机工具将image烧制到手机中,我们也可以使用fastboot命令很方便的将image文件烧制到系统中。下面为fastboot的使用方法:

1.开机状态下执行

adb reboot bootloader(执行命令后系统会关机重启,进入fastboot模式)

2.烧写system.img

fastboot flash system system.img

如果要烧制boot.img,那么就执行fastboot flash boot boot.img,其他image也一样。

3.重启

fastboot reboot

简单几步就可以快速将我们编译出来的文件烧制到手机中。

bootchart

bootchart是一个用于linux启动过程性能分析的开源软件工具,在系统启动过程自动收集CPU占用率、进程等信息,并以图形方式显示分析结果,可用作指导优化系统启动过程。bootchart详细使用说明请参考《Android7.0 bootchart工具使用说明

LOG分析

在调试Android系统时如果要实时的查看输出的log信息就可以使用adb logcat -vthreadtime或者adb logcat在终端输出需要的log信息,在5.1及其之前的版本需要adb logcat后需要加上-vthreadtime 意思是将输出时间以及进程线程信息,5.1之后的版本系统自动添加了时间与进程线程信息,直接用adb logcat就可以。

而更多的时候我们需要分析log文件,也就是在系统运行时会将log信息输出在log文件中,以便在出现问题时让开发人员进行分析,下面讲几个场景的关键LOG信息。

开机LOG

在分析开机log时通过根据开机流程进行分段分析,这里省略bootloader中log,首先从执行kernel完成分析,到启动launcher分析结束,来看其中执行了那些过程,如果开机流程出现问题,就可以定位哪个流程出现问题。

[plain] view plaincopy

  1. //开始启动init进程,也就是kernel启动完成,取时间戳2.172934s,为启动kernel所耗时.
  2. [01-01 08:30:04.349] <13>[    2.172934] c5 init: init started!
  3. //开始启动zygote,使用时间戳相减4.281027-2.172934计算出启动init进程到启动zygote耗时2.1s.
  4. [01-01 08:30:04.367] <13>[    4.281027] c0 init: Starting service 'zygote'...
  5. //进入zygote,由于kernel时间与android不能相减,所以无法计算启动zygote到进入zygote所花费时间.
  6. A001-01 08:30:05.036  2810  2810 D AndroidRuntime: >>>>>> START com.android.internal.os.ZygoteInit uid 0 <<<<<<
  7. //进入SystemServer,使用android时间08:30:08.629-08:30:05.036 获得,从进入zygote到SystemServer耗时
  8. A101-01 08:30:08.629  3285  3285 I SystemServer: Entered the Android system server!
  9. //开始初始化Package, 使用android时间相减,获取进入SystemServer到初始化Package的耗时.
  10. A101-01 08:30:09.021  3285  3285 I SystemServer: Package Manager
  11. //扫描解析应用耗时,可以直接获取1.544 seconds
  12. A101-01 08:30:10.813  3285  3285 I PackageManager: Time to scan packages: 1.544 seconds
  13. //开始执行network systemReady函数,使用android时间相减,获取初始化Package完成到开始执行network systemReady函数的耗时.
  14. A101-01 08:30:14.285  3285  3285 D NetworkManagement: enabling bandwidth control
  15. //network执行完相关命令,使用android时间相减,获取执行network执行相关命令耗时.
  16. A101-01 08:30:15.475  3285  3285 I SystemServiceManager: Starting phase 600
  17. //启动launcher, 使用android时间相减,获取执行network命令完成,到启动launcher耗时
  18. A101-01 08:30:15.915  3285  3285 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher3/.Launcher} from uid 0 on display 0

关机LOG

在分析关机log时,是从长按power键,点击确认关机,到灭屏震动关机。关机主要经过的流程为发送关机广播,关闭AMS,PMS,关闭移动数据,卸载sd卡等流程,最后调用power往底层系统配置中写入对应的信息,底层读取信息,进行关机。

[plain] view plaincopy

  1. //按确认键,开始关机
  2. 01-01 12:49:10.410  1147  1226 I ShutdownThread: shutdown goto shutdownInner
  3. //发送关机广播,使用android时间相减,获得关机到发送关机广播之间耗时
  4. 01-01 12:49:10.498  1147  2504 I ShutdownThread: Sending shutdown broadcast...
  5. //开始shutdown activity manager, 使用android时间相减,获得关机广播处理耗时
  6. 01-01 12:49:10.637  1147  2504 I ShutdownThread: Shutting down activity manager...
  7. //开始关闭蜂窝网,使用android时间相减,获得开机shutdown activity manager到关闭蜂窝网耗时
  8. 01-01 12:49:10.746  1147  2522 W ShutdownThread: Turning off cellular radios...
  9. //开始关闭Radio,获得关闭蜂窝网到开始关闭Radio耗时
  10. 01-01 12:49:10.753  1147  2522 I ShutdownThread: Waiting for NFC, Bluetooth and Radio...
  11. //关闭Radio完成,使用android时间相减,获得关闭Radio耗时,该流程可能耗时较长.重点
  12. 01-01 12:49:11.255  1147  2522 I ShutdownThread: NFC, Radio and Bluetooth shutdown complete.
  13. //开始关闭MountService,使用android时间相减,获得关闭Radio完成到关闭MountService耗时.
  14. 01-01 12:49:11.257  1147  2504 I ShutdownThread: Shutting down MountService
  15. //关闭MountService完成,使用android时间相减,获得关闭MountService耗时.该流程可能耗时较长.重点
  16. 01-01 12:49:11.268  1147  1304 W ShutdownThread: Result code 0 from MountService.shutdown
  17. //调用底层接口,关机完成.
  18. 01-01 12:49:11.776  1147  2504 I ShutdownThread: Performing low-level shutdown...

首启动应用LOG

在分析分析应用启动问题时,我们通常分析event log信息,使用命令adb logcat -b events,其中的log信息主要为应用的生命周期信息。通过查看生命周期信息来分析,应用是否行为异常。

首次启动

[plain] view plaincopy

  1. //开始启动activity
  2. 07-29 10:26:57.033  1173  1995 I am_create_activity: [0,102422011,29,com.android.dialer/.DialtactsActivity,android.intent.action.MAIN,NULL,NULL,270532608]
  3. //launcher pause完成。
  4. 07-29 10:26:57.109  2009  2009 I am_on_paused_called: [0,com.android.launcher3.Launcher]
  5. //进程开始创建,与开始启动activity时间相减,获得准备工作耗时.
  6. 07-29 10:26:57.142  1173  1996 I am_proc_start: [0,5164,10038,com.android.dialer,activity,com.android.dialer/.DialtactsActivity]
  7. //进程bound完成,与进程创建之间这个过程可以理解为进程创建的时间。为创建进程耗时.
  8. 07-29 10:26:57.195  1173  1404 I am_proc_bound: [0,5164,com.android.dialer]
  9. //ams向应用发消息进行启动activity操作
  10. 07-29 10:26:57.199  1173  1404 I am_restart_activity: [0,102422011,29,com.android.dialer/.DialtactsActivity]
  11. //activity resume执行完成,与restart_activity之间这个可以理解为Activity的生命周期执行时间。为生命周期耗时
  12. 07-29 10:26:57.394  5164  5164 I am_on_resume_called: [0,com.android.dialer.DialtactsActivity]
  13. //这里activity显示完成,当前Activity显示过程644ms,整个显示过程644ms。
  14. //从activity resume完成到这个log之间可以理解为广义上的绘制过程(measure,layout,draw,render)。
  15. 07-29 10:26:57.757  1173  1356 I am_activity_launch_time: [0,102422011,com.android.dialer/.DialtactsActivity,644,644]

非首次启动

[plain] view plaincopy

  1. //开始启动activity,到launcher pause完成。
  2. 01-01 13:26:59.645  1162  1733 I am_create_activity: [0,233918075,10,com.android.messaging/.ui.conversationlist.ConversationListActivity,android.intent.action.MAIN,NULL,NULL,270532608]
  3. //launcher pause完成。
  4. 07-29 10:26:57.109  2009  2009 I am_on_paused_called: [0,com.android.launcher3.Launcher]
  5. //ams向应用发消息进行启动activity操作,准备工作
  6. 01-01 13:26:59.710  1162  1439 I am_restart_activity: [0,233918075,10,com.android.messaging/.ui.conversationlist.ConversationListActivity]
  7. //activity resume执行完成,与restart_activity之间这个可以理解为Activity的生命周期执行时间。
  8. 01-01 13:26:59.782  2189  2189 I am_on_resume_called: [0,com.android.messaging.ui.conversationlist.ConversationListActivity]
  9. //这里activity显示完成,当前Activity显示过程168ms,整个显示过程168ms。
  10. //从activity resume完成到这个log之间可以理解为广义上的绘制过程(measure,layout,draw,render)。
  11. 01-01 13:26:59.871  1162  1283 I am_activity_launch_time: [0,233918075,com.android.messaging/.ui.conversationlist.ConversationListActivity,168,168]

亮屏关键LOG

[plain] view plaincopy

  1. //kernel中断key事件,ScanCode:116为Power键,value:1为down事件
  2. <6>[41051.961488] c1 [SPRD_KEY_INFO]Key:Power Key ScanCode:116 value:1
  3. //InputReader获取power键事件,code=116为power键
  4. 01-02 08:04:44.016   600   643 D InputReader: processEventsLocked: type=1 Count=2 code=116 value=1 deviceId=2
  5. //Power收到亮屏调用,开始亮屏
  6. 01-02 08:04:44.037   600   643 I PowerManagerService: Waking up from sleep (uid 1000)...
  7. //开始block亮屏,直到keyguard与windows绘制完成
  8. 01-02 08:04:44.052   600   622 I DisplayPowerController: Blocking screen on until initial contents have been drawn.
  9. //开始绘制keyguard
  10. 01-02 08:04:44.052   600   622 I WindowManager: Screen turning on...
  11. //tosuspend_disable()耗时283s,有时为setPowerMode耗时长
  12. 01-02 08:04:44.347   600   676 D PowerManagerService-JNI: Excessive delay in autosuspend_disable() while
  13. //yguard绘制完成
  14. 01-02 08:04:44.504   600   700 D WindowManager: mKeyguardDelegate.ShowListener.onDrawn.
  15. 01-02 08:04:44.504   600   614 W WindowManager: Setting mKeyguardDrawComplete
  16. //windows绘制完成
  17. 01-02 08:04:44.551   600   620 I WindowManager: All windows ready for display!
  18. 01-02 08:04:44.551   600   614 W WindowManager: Setting mWindowManagerDrawComplete
  19. //block亮屏,总共blocked亮屏505ms
  20. 01-02 08:04:44.557   600   622 I DisplayPowerController: Unblocked screen on after 505 ms
  21. //屏幕亮度,往节点中写亮度值
  22. 01-02 08:04:44.558   600   676 D LIGHTS  : file:vendor/sprd/modules/lights/lights.c, func:set_light_backlight, brightness=25
  23. 01-02 08:04:44.559   600   676 E LIGHTS  : file:vendor/sprd/modules/lights/lights.c, func:write_int, path=/sys/class/backlight/sprd_backlight/brightness, value=25

来电亮屏LOG

[plain] view plaincopy

  1. //创建dialer进程
  2. 12-22 15:46:23.704   595   595 I ActivityManager: Start proc 5067:com.android.dialer/u0a1 for service com.android.dialer/com.android.incallui.InCallServiceImpl
  3. //来电响铃
  4. 12-22 15:46:23.736   595  5083 I Telecom : AsyncRingtonePlayer: Play ringtone.
  5. //启动InCallActivity
  6. 12-22 15:46:24.410   595  1016 I ActivityManager: START u0 {act=android.intent.action.MAIN flg=0x10040000 cmp=com.android.dialer/com.android.incallui.InCallActivity (has extras)} from uid 10001 on display 0
  7. //显示InCallActivity
  8. 12-22 15:46:25.715   595   615 I am_activity_launch_time: [0,134650581,com.android.dialer/com.android.incallui.InCallActivity,1293,1299]
  9. //power收到亮屏调用
  10. 12-22 15:46:25.730   595   615 I PowerManagerService: Waking up from sleep due toandroid android.server.wm:TURN_ON (uid 1000)...
  11. //点亮屏幕
  12. A012-22 15:46:26.220   595   679 D LIGHTS  : file:vendor/sprd/modules/lights/lights.c, func:set_light_backlight, brightness=25
  13. A012-22 15:46:26.221   595   679 E LIGHTS  : file:vendor/sprd/modules/lights/lights.c, func:write_int, path=/sys/class/backlight/sprd_backlight/brightness, value=25

灭屏LOG

[plain] view plaincopy

  1. //kernel中断key事件,ScanCode:116为Power键,value:1为down事件
  2. <6>[42586.507314] c1 [SPRD_KEY_INFO]Key:Power Key ScanCode:116 value:1
  3. //value:0为up事件
  4. <6>[42586.660288] c1 [SPRD_KEY_INFO]Key:Power Key ScanCode:116 value:0
  5. //Input收到power键down事件
  6. 01-06 13:25:48.460  3339  3447 D InputReader: processEventsLocked: type=1 Count=2 code=116 value=1 deviceId=2
  7. //Input收到power键up事件
  8. 01-06 13:25:48.643  3339  3447 D InputReader: processEventsLocked: type=1 Count=2 code=116 value=0 deviceId=2
  9. //短按power键,power开始灭屏
  10. 01-06 13:25:48.643  3339  3447 I PowerManagerService: Going to sleep due to power button (uid 1000)...
  11. //设置全局变量,通知keyguard灭屏了
  12. 01-06 13:25:48.645  3339  3361 I WindowManager: Screen turned off...
  13. //设置屏幕亮度为0
  14. 01-06 13:25:48.645  3339  3493 D LIGHTS  : file:vendor/sprd/modules/lights/lights.c, func:set_light_backlight, brightness=0
  15. 01-06 13:25:48.645  3339  3493 E LIGHTS  : file:vendor/sprd/modules/lights/lights.c, func:write_int, path=/sys/class/backlight/sprd_backlight/brightness, value=0

添加LOG信息

java层添加

当在调试系统代码时,如果要确认代码是否走了某个流程,就可以添加log信息,如果执行某项操作可以将该行log打印出来就说明走了该流程。
[java] view plaincopy

  1. importandroid.util.Log;//导入LOG包
  2. privatestaticString getActiveSubscriberId(Context context,intsubId) {
  3. finalTelephonyManager tele = TelephonyManager.from(context);
  4. String retVal = tele.getSubscriberId(subId);
  5. Log.d(TAG, "getActiveSubscriberId="+ retVal +" subId="+ subId);//添加log信息
  6. returnretVal;
  7. }

如果想知道某行代码是怎么调用过来的,他的调用关系是什么,就可以通过打印堆栈的方式来确认。具体方式如下;

[java] view plaincopy

  1. try{
  2. thrownewException("Call Stack Trace");
  3. catch(Exception e) {
  4. Log.i("kevin","xxx", e);
  5. }

例如在唤醒屏幕流程,如果想要分析wakeUpInternal是怎么调用过来的,就可以打印堆栈的方式来确认调用关系。

[java] view plaincopy

  1. privatevoidwakeUpInternal(longeventTime, String reason,intuid, String opPackageName,
  2. intopUid) {
  3. synchronized(mLock) {
  4. try{
  5. thrownewException("Call Stack Trace");
  6. catch(Exception e) {
  7. Log.i("kevin","xxx", e);
  8. }
  9. if(wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {
  10. updatePowerStateLocked();
  11. }
  12. }
  13. }

当我们修改好代码后编译services.jar,将services.jar push到手机中,重启,按power键亮灭屏就可以看到如下信息。

C++层添加

如果想要在C++层添加log信息,需要在对应的Android.mk文件中添加下面代码,添加共享库。

[cpp] view plaincopy

  1. LOCAL_SHARED_LIBRARIES := libutils

用如下log可以打印C++层的信息。

[cpp] view plaincopy

  1. ALOGD("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);

如果要在C++层中打印对应堆栈,使用如下代码:

[cpp] view plaincopy

  1. #include <utils/CallStack.h>
  2. CallStack stack;
  3. stack.update();
  4. stack.log("kevin");

示例代码如下:

[cpp] view plaincopy

  1. voidNuPlayer::start() {
  2. CallStack stack;
  3. stack.update();
  4. stack.log("kevin");
  5. (newAMessage(kWhatStart,this))->post();
  6. }

输出堆栈如下:

可以使用前面学习的addr2line

可以看到具体的代码调用。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fu_kevin0606/article/details/79616216

Android Framework常用工具及LOG调试方法相关推荐

  1. Android 系统(78)---《android framework常用api源码分析》之 app应用安装流程

    <android framework常用api源码分析>之 app应用安装流程 <android framework常用api源码分析>android生态在中国已经发展非常庞大 ...

  2. Android开发常用工具类集合

    转载自:https://blog.csdn.net/xiaoyi_tdcq/article/details/52902844 Android开发常用工具类集合 android开发中为了避免重复造轮子, ...

  3. Android开发常用工具,编译调试工具,性能优化工具,工具集

    分析具体耗时的Trace view;布局复杂度工具Hierarchy View;应用启动时间;Memory.CPU.Network分析;静态代码检查工具Lint;程序稳定性monkey.adb调试桥. ...

  4. Android开发常用工具类

    来源于http://www.open-open.com/lib/view/open1416535785398.html 主要介绍总结的Android开发中常用的工具类,大部分同样适用于Java. 目前 ...

  5. 用什么软件测试光纤稳定性,工欲善其事,谈谈光纤的几种常用工具用途及使用方法!...

    随着物联网.5G技术等快速发展,智能化行业中光缆施工和维护的工作逐渐增加,促使各种光纤工具的需求量上升,市面上常见的光纤工具有光纤剥线钳.光缆剥皮器.光缆切割剪等,种类繁多,各种工具的用途也各不相同, ...

  6. Android开发常用工具推荐

    前言 本文阅读时间:4 min 30 s 首先必须声明,我个人用的是Windows系统,所以我的推荐也是基于Windows的.至于什么时候推荐Mac版的工具,等我有钱换了Mac再说! 正文 好了,大餐 ...

  7. (转)Android开发常用工具类

    原地址:http://blog.csdn.net/axi295309066/article/details/52884973 不管是前端,后端,还是我们的Android开发,实际工作中都会用到很多的工 ...

  8. 在Android C/C++层添加LOG调试(LOGI\LOGD\LOGE...)输出支持

    最近在研究Android 2.3.3源代码的C/C++层,需要对代码进行一些调试,但是奇怪的是,直接添加LOGD("XXXXXXXX");,使用logcat却看不到任何输出,换成L ...

  9. 在Android C/C++层添加LOG调试(LOGI/LOGD/LOGE

    最近在研究Android 2.3.3源代码的C/C++层,需要对代码进行一些调试,但是奇怪的是,直接添加LOGD("XXXXXXXX");,使用logcat却看不到任何输出,换成L ...

最新文章

  1. 获赞23w+在B站一夜爆火,大写的牛B!程序员进阶网盘资源(有链接和提取码)...
  2. [BZOJ1131][POI2008]Sta
  3. 网易智慧企业Node.js实践(1) | Node应用架构设计和React同构
  4. 如何获取高精度CV模型?快来试试百度EasyDL超大规模视觉预训练模型
  5. go mysql 查询语句_01 MySQL-初识MySQL-查询语句的执行流程-Go语言中文社区
  6. form子句语法错误_用示例语法解释SQL的子句
  7. 虚拟寄存器,虚拟堆栈与真实寄存器,真实堆栈如何对应
  8. 计算机 未来哪种技术稀缺,2015级职业生涯规划考试试题
  9. 3 矩阵运算_FlyAI小课堂:小白学PyTorch(11) 常见运算详解
  10. define和typedef区别
  11. 【原创】SSAS-引用维度与多数据源、多数据源视图引发分区错误
  12. Java之Socket实现文件传输
  13. 万能声卡驱动win10_ASIO驱动(多通道版)-无驱外置USB声卡电音驱动
  14. 【MATLAB】 曲面的绘制
  15. 按哪个键进入BIOS设置
  16. windows平台简单的FTP服务器,无需安装
  17. has text relocations
  18. Win10 ntoskrnl.exe蓝屏解决
  19. 使用AJAX的10个商业动机 {转}
  20. amd显卡用黑苹果输出黑屏_黑苹果用杂交法修改framebuffer开启显卡所有输出端口成功...

热门文章

  1. 解决Android抽屉被击穿问题
  2. 如何在属性面板中增加一个属性-UI界面编辑器(XproerUI)教程
  3. Sublime Text 3 中文乱码的解决方法
  4. UpdatePanel里使用FileUpload
  5. 大宝的读后感:(转载)
  6. 推荐《求医不如求己》,实用
  7. Python学习笔记: Python 标准库概览二
  8. 单核工作法12:现在专注一件事(下)
  9. Qt学习笔记(一) 第一个Qt应用程序
  10. python中调用c库