概述
Framework开发是一项非常繁琐复杂的工作,需要阅读大量的源代码,分析及其多的LOG信息来定位错误位置。这个时候如果使用一些工具或者知道如何定位重要LOG信息,就可以使一些复杂的工作变的简单很多,使我们分析问题的效率变得更快,不再为阅读大量的源代码而感到一筹莫展。本文将针对一些场景讲解如何分析系统LOG信息,如何添加LOG定位错误信息,以及常用工具以及使用方法。
常用工具
HierarchyViewer
HierarchyViewer是随Android SDK发布的工具,位置在sdk的tools文件夹下,名为hierarchyviewer。它是Android自带的非常有用而且使用简单的工具,能够让我们从可视化的角度直观地获得UI布局设计结构和各种属性的信息,帮助我们优化布局设计。打开HierarchyViewer后我们可以看到当前view的布局,如下图所示。
DDMS
DDMS 的全称是Dalvik Debug Monitor Service,是 Android 开发环境中的Dalvik虚拟机调试监控服务。它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息、Logcat、广播状态信息、模拟电话呼叫、接收SMS、虚拟地理坐标等等。DDMS打开界面如下:
左侧的Devices一栏会列出已连接的设备,点击设备名称左侧三角符号图标会列出该设备运行中的进程的app包名。
模拟按键
使用命令adb shell input keyevent + 对应的键值,可以模拟对应的操作。手机系统中主要的键值如下:
/** Key code constant: Home key.
* This key is handled by the framework and is never delivered to applications. */
public static final int KEYCODE_HOME = 3; //Home键
/** Key code constant: Back key. */
public static final int KEYCODE_BACK = 4; //Back键
/** Key code constant: Call key. */
public static final int KEYCODE_CALL = 5; //打电话
/** Key code constant: End Call key. */
public static final int KEYCODE_ENDCALL = 6; //挂断电话
/** Key code constant: Volume Up key.
* Adjusts the speaker volume up. */
public static final int KEYCODE_VOLUME_UP = 24; //调大声音
/** Key code constant: Volume Down key.
* Adjusts the speaker volume down. */
public static final int KEYCODE_VOLUME_DOWN = 25; //调小声音
/** Key code constant: Power key. */
public static final int KEYCODE_POWER = 26; //电源键
/** Key code constant: Camera key.
* Used to launch a camera application or take pictures. */
public static final int KEYCODE_CAMERA = 27; //相机按键
/** Key code constant: Clear key. */
public static final int KEYCODE_CLEAR = 28; //清理
/** Key code constant: Space key. */
public static final int KEYCODE_SPACE = 62; //空格键
/** Key code constant: Backspace key.
* Deletes characters before the insertion point, unlike {@link #KEYCODE_FORWARD_DEL}. */
public static final int KEYCODE_DEL = 67; //删除键
/** Key code constant: Menu key. */
public static final int KEYCODE_MENU = 82; //菜单键
当我们要模拟power键亮灭屏事件就可以执行下面命令:
adb shell input keyevent 26
模拟别的按键事件同理。
而adb shell getevent / adb shell sendevent是发送对应的事件,包括触屏,按键等事件。
am命令
有时候我们在调试系统时可以在终端使用am命令来发送广播,打开Activity,启动Service等操作,十分方便。am的详细操作如下,我们可以通过adb shell am + 对应命令,就可操作。
usage: am [subcommand] [options]
usage: am start [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]
[--sampling INTERVAL] [-R COUNT] [-S]
[--track-allocation] [--user <USER_ID> | current] <INTENT> //可以通过该命令启动对应Activity
am startservice [--user <USER_ID> | current] <INTENT> //启动服务
am stopservice [--user <USER_ID> | current] <INTENT> //停止服务
am force-stop [--user <USER_ID> | all | current] <PACKAGE> //通过包名强制停止应用
am kill [--user <USER_ID> | all | current] <PACKAGE> //根据进程号杀死进程
am kill-all //杀掉所有后台进程
am broadcast [--user <USER_ID> | all | current] <INTENT> //发送广播
am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]
[--user <USER_ID> | current]
[--no-window-animation] [--abi <ABI>] <COMPONENT>
am profile start [--user <USER_ID> current] [--sampling INTERVAL] <PROCESS> <FILE> //抓取traceview
am profile stop [--user <USER_ID> current] [<PROCESS>] //停止抓取traceview
am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>
am set-debug-app [-w] [--persistent] <PACKAGE>
am clear-debug-app
am set-watch-heap <PROCESS> <MEM-LIMIT>
am clear-watch-heap
am bug-report [--progress]
am monitor [--gdb <port>]
am hang [--allow-restart]
am restart //重启应用
am idle-maintenance
am screen-compat [on|off] <PACKAGE>
am package-importance <PACKAGE>
am to-uri [INTENT]
am to-intent-uri [INTENT]
am to-app-uri [INTENT]
am switch-user <USER_ID>
am start-user <USER_ID>
am unlock-user <USER_ID> [TOKEN_HEX]
am stop-user [-w] [-f] <USER_ID>
am stack start <DISPLAY_ID> <INTENT>
am stack movetask <TASK_ID> <STACK_ID> [true|false] //stack相关
am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
am stack resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
am stack resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]
am stack size-docked-stack-test: <STEP_SIZE> <l|t|r|b> [DELAY_MS]
am stack move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
am stack positiontask <TASK_ID> <STACK_ID> <POSITION>
am stack list //列出系统中的所有stack
am stack info <STACK_ID> //stack信息
am stack remove <STACK_ID> //移除stack
am task lock <TASK_ID>
am task lock stop
am task resizeable <TASK_ID> [0 (unresizeable) | 1 (crop_windows) | 2 (resizeable) | 3 (resizeable_and_pipable)]
am task resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>
am task drag-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]
am task size-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]
am get-config
am suppress-resize-config-changes <true|false>
am set-inactive [--user <USER_ID>] <PACKAGE> true|false
am get-inactive [--user <USER_ID>] <PACKAGE>
am send-trim-memory [--user <USER_ID>] <PROCESS>
[HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]
am get-current-user
am start: start an Activity. Options are: //启动Activity详细使用方法
-D: enable debugging
-N: enable native debugging
-W: wait for launch to complete
--start-profiler <FILE>: start profiler and send results to <FILE>
--sampling INTERVAL: use sample profiling with INTERVAL microseconds
between samples (use with --start-profiler)
-P <FILE>: like above, but profiling stops when app goes idle
-R: repeat the activity launch <COUNT> times. Prior to each repeat,
the top activity will be finished.
-S: force stop the target app before starting the activity
--track-allocation: enable tracking of object allocations
--user <USER_ID> | current: Specify which user to run as; if not
specified then run as the current user.
--stack <STACK_ID>: Specify into which stack should the activity be put.
am startservice: start a Service. Options are:
--user <USER_ID> | current: Specify which user to run as; if not
specified then run as the current user.
am stopservice: stop a Service. Options are:
--user <USER_ID> | current: Specify which user to run as; if not
specified then run as the current user.
am force-stop: