adb shell


dumpsys activity|grep mResume

或者

adb shell

dumpsys window windows | grep -E 'mCurrentFocus'

copy 自http://www.cnblogs.com/tt_mc/p/4269833.html

使用adb shell dumpsys检测Android的Activity任务栈

谈起Android程序开发,就需要了解其四个主要的部件:Activity、Service、ContentProvider、BroadcastReceiver。而其中Activity是唯一直接控制程序界面呈现,直面用户操作的部件(当然BrowadCastReceiver也能通过桌面控件(App Widgets)来呈现有限的操作界面)。Android对于Activity有严格的生命周期控制,以限制开发者在适当的回调函数里的放上合适的代码。对于多个Activity的转换,Android也有非常好的管理和流畅的切换,对此Android还引入了任务栈(Task Stack)的概念,这个概念对于Android设备上得返回按键有极其重要的联系。

(大部分文档都将其表述为Tasks and Back Stack,但从官方文档的描述来看,Android的相对于Activity讲到的Task都视为一个存放Activities的Stack,所以将其称为Task Stack也不为过。)

在AndroidManifest中申明所要用到的Activity时可以设置不同的launchMode来得到不同的Activity“启动”效果。在使用startActivity开启新的Activity时,传入的Intent也可以设置不同的Flag来达到不同的效果。另一方面,在Activity启动时它可能又开启了另一个Activity,或者调用了finish()函数终结了Activity。

这使得Activity栈变得无法掌握,有时候按下返回按钮或者点击关闭当前Activity的操作,都不知道Android系统会把程序带到那个Activity,不确定这是否是最后一个Activity以致退出了整个程序。亦或者一些按钮和操作循环产生Activity而造成内存膨胀。对于这些问题,如果能够在调试期间知道当前任务栈的情况,就能很方便的观察和发现问题存在的原因,进而选择正确的launchMode,设置恰当IntentFlag来使程序达到预期的效果。

通过ActivityManager获取状态

Android提供了ActivityManger来帮助开发者了解运行期间的状态,通过调用getRunningTasks(int)方法,就可以在得到RunningTaskInfo的列表,其代表着当前Android设备正在运行着的Task。从RunningTaskInfo中又可以进一步得到更多的信息。

  1. ActivityManager am =(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
  2. List <RunningTaskInfo> runningTaskInfoList= am.getRunningTasks(10);
  3. for(RunningTaskInfo runningTaskInfo: runningTaskInfoList){
  4. log ("id: "+ runningTaskInfo.id);
  5. log ("description: "+ runningTaskInfo.description);
  6. log ("number of activities: "+ runningTaskInfo.numActivities);
  7. log ("topActivity: "+ runningTaskInfo.topActivity);
  8. log ("baseActivity: "+ runningTaskInfo.baseActivity.toString());
  9. }

例如文中提供的示例程序中定义了4个具有不同launchMode的Activity,每点击一次菜单栏上得选项就会弹出一个新的Activity(或者将指定Singleton的Activity置前)。

Activity上显示的数字则指示startActivity()被第几次调用时开启了这个Activity。有一些Singleton的会显示多个数字,也表明它是被复用的。

因为在onCreate()方法上放置了上述代码,所以观察log就能发现当前有多少个Task在被执行,每个Task又有多少个Activities。

D/IDER    ( 3700): =====================D/IDER    ( 3700): ---------------------D/IDER    ( 3700): id: 25D/IDER    ( 3700): description: nullD/IDER    ( 3700): number of activities: 4D/IDER    ( 3700): topActivity: ComponentInfo{com.iderzheng/com.iderzheng.StandardActivity}D/IDER    ( 3700): baseActivity: ComponentInfo{com.iderzheng/com.iderzheng.SingleTaskActivity}D/IDER    ( 3700): ---------------------D/IDER    ( 3700): id: 24D/IDER    ( 3700): description: nullD/IDER    ( 3700): number of activities: 1D/IDER    ( 3700): topActivity: ComponentInfo{com.iderzheng/com.iderzheng.SingleInstanceActivity}D/IDER    ( 3700): baseActivity: ComponentInfo{com.iderzheng/com.iderzheng.SingleInstanceActivity}D/IDER    ( 3700): ---------------------D/IDER    ( 3700): id: 23D/IDER    ( 3700): description: nullD/IDER    ( 3700): number of activities: 2D/IDER    ( 3700): topActivity: ComponentInfo{com.iderzheng/com.iderzheng.StandardActivity}D/IDER    ( 3700): baseActivity: ComponentInfo{com.iderzheng/com.iderzheng.MainActivity}D/IDER    ( 3700): ---------------------D/IDER    ( 3700): id: 1D/IDER    ( 3700): description: nullD/IDER    ( 3700): number of activities: 1D/IDER    ( 3700): topActivity: ComponentInfo{com.android.launcher/com.android.launcher2.Launcher}D/IDER    ( 3700): baseActivity: ComponentInfo{com.android.launcher/com.android.launcher2.Launcher}

缺点

必须在程序中注入调试代码,因为要控制在发布时代码必须被清理了。RunningTaskInfo虽然能够告诉我们有多少个Activity保存在其上,但是没有提供完整的列表,只能看到头尾两个Activity。给出的两个Activity的属性:topActivity和baseActivity也只是ComponentName类型,并非真实的Activity对象,因此除了类的名字没有其他更多信息。

手动记录和管理Activities栈

Activity的创建和销毁都会有相应的回调函数:onCreate()onDestroy()。因此可以自建一个静态全局Stack对象,在onCreate()时候讲当前Activity对象加入到Stack中,而在onDestroy()时把它从Stack中移除。这样我们就随时可以知道当前Activity的详细情况了。

缺点

要让所有Activity的onCreate()onDestroy()方法上有对应的进出栈的方法,要么有统一的基类,要么强制每个Activity都加入这些代码,但两种方式都不完美。另外也很难模拟singleTask这类会创建出新的Task的情况,这时光使用一个Stack就不足够了,要考虑所有的情况又不太可能。再者如同使用ActivityManager一样这些代码也应该只出现在调试阶段

使用adb shell指令

Android还为开发者提供了adb(Android Debug Bridge),这是非常强大的调试工具。最常用的自然是logcat来显示日志记录。另外一个很强大的指令就是这里要提到的dumpsysdumpsys还可以添加不同的参数来指示需要输出哪一类Service的信息。对于本文提到的内容,需要查看的就是activity,指令就是:

adb shell dumpsys activity


输入上述指令,就能得到关于设备非常长的一段讯息,单是也能清晰看出它们比较详细的分类

ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)  * PendingIntentRecord{42b05f20 com.android.vending startService}  ... ... ... ...ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)  Historical broadcasts [foreground]:  #0: BroadcastRecord{430d2fb8 u-1 android.intent.action.TIME_TICK}    act=android.intent.action.TIME_TICK flg=0x50000014 (has extras)    extras: Bundle[{android.intent.extra.ALARM_COUNT=1}]  ... ... ... ...ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)  Published single-user content providers (by class):  * ContentProviderRecord{429d18a8 u0 com.android.phone/.IccProvider}    proc=ProcessRecord{429765d8 858:com.android.phone/1001}    singleton=true    authority=icc  ... ... ... ...ACTIVITY MANAGER SERVICES (dumpsys activity services)  User 0 active services:  * ServiceRecord{429f8668 u0 com.android.bluetooth/.hid.HidService}    app=null    created=-1h44m27s317ms started=false connections=0  ... ... ... ...ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)  Stack #0:    Task id #28      TaskRecord{43525058 #28 A=com.android.systemui U=0 sz=1}      Intent { act=com.android.systemui.recent.action.TOGGLE_RECENTS flg=0x10c00000 cmp=com.android.systemui/.recent.RecentsActivity (has extras) }        Hist #0: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28}          Intent { act=com.android.systemui.recent.action.TOGGLE_RECENTS flg=0x10800000 cmp=com.android.systemui/.recent.RecentsActivity bnds=[328,886][656,1176] }          ProcessRecord{42968230 695:com.android.systemui/u0a12}  ... ... ... ...ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)  Process LRU list (sorted by oom_adj, 28 total, non-act at 3, non-svc at 3):    PERS #27: sys   F/ /P  trm: 0 605:system/1000 (fixed)  ... ... ... ...

每一个类别都有一个括号内容,给出了更加详细的指令来查看该类别下更多具体内容。因此再来尝试指令:

db shell dumpsys activity activities

就能看到下边的结果

CTIVITY MANAGER ACTIVITIES (dumpsys activity activities)  Stack #0:    Task id #28    * TaskRecord{43525058 #28 A=com.android.systemui U=0 sz=1}      ... ... ... ...      * Hist #0: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28}          ... ... ... ...    Task id #1    * TaskRecord{429a35f8 #1 A=com.android.launcher U=0 sz=1}      ... ... ... ...      * Hist #0: ActivityRecord{429a1760 u0 com.android.launcher/com.android.launcher2.Launcher t1}          ... ... ... ...    Running activities (most recent first):      TaskRecord{43525058 #28 A=com.android.systemui U=0 sz=1}        Run #1: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28}      TaskRecord{429a35f8 #1 A=com.android.launcher U=0 sz=1}        Run #0: ActivityRecord{429a1760 u0 com.android.launcher/com.android.launcher2.Launcher t1}    mLastPausedActivity: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28}  Stack #1:    Task id #25    * TaskRecord{42b0ee20 #25 I=com.iderzheng/.SingleTaskActivity U=0 sz=5}      numActivities=5 rootWasReset=false userId=0 mTaskType=0 numFullscreen=5 mOnTopOfHome=true      intent={cmp=com.iderzheng/.SingleTaskActivity}      realActivity=com.iderzheng/.SingleTaskActivity      Activities=[ActivityRecord{42a7e160 u0 com.iderzheng/.SingleTaskActivity t25}, ActivityRecord{42bffdf0 u0 com.iderzheng/.StandardActivity t25}, ActivityRecord{42e9e8f8 u0 com.iderzheng/.SingleTopActivity t25}, ActivityRecord{434c2238 u0 com.iderzheng/.StandardActivity t25}, ActivityRecord{4279d2d8 u0 com.iderzheng/.SingleTopActivity t25}]      askedCompatMode=false      lastThumbnail=null lastDescription=null      lastActiveTime=6229735 (inactive for 357s)      * Hist #4: ActivityRecord{4279d2d8 u0 com.iderzheng/.SingleTopActivity t25}          packageName=com.iderzheng processName=com.iderzheng          launchedFromUid=10124 launchedFromPackage=com.iderzheng userId=0          app=ProcessRecord{4312cbb0 3700:com.iderzheng/u0a124}          Intent { cmp=com.iderzheng/.SingleTopActivity bnds=[328,580][656,870] }          frontOfTask=false task=TaskRecord{42b0ee20 #25 I=com.iderzheng/.SingleTaskActivity U=0 sz=5}          taskAffinity=com.iderzheng          realActivity=com.iderzheng/.SingleTopActivity          baseDir=/data/app/com.iderzheng-1.apk          dataDir=/data/data/com.iderzheng          stateNotNeeded=false componentSpecified=true mActivityType=0          compat={320dpi} labelRes=0x7f0a0013 icon=0x7f020057 theme=0x7f0b0000          config={1.0 310mcc?mnc en_US ldltr sw384dp w384dp h567dp 320dpi nrml port finger -keyb/v/h -nav/h s.7}          launchFailed=false launchCount=0 lastLaunchTime=-1h40m33s397ms          haveState=false icicle=null          state=RESUMED stopped=false delayedResume=false finishing=false          keysPaused=false inHistory=true visible=true sleeping=false idle=true          fullscreen=true noDisplay=false immersive=false launchMode=1          frozenBeforeDestroy=false thumbnailNeeded=false forceNewConfig=false          mActivityType=APPLICATION_ACTIVITY_TYPE          thumbHolder: 42b0ee20 bm=null desc=null          waitingVisible=false nowVisible=true lastVisibleTime=-5m56s862ms    ... ... ... ...    Running activities (most recent first):      TaskRecord{42b0ee20 #25 I=com.iderzheng/.SingleTaskActivity U=0 sz=5}        Run #7: ActivityRecord{4279d2d8 u0 com.iderzheng/.SingleTopActivity t25}      TaskRecord{429e9558 #24 A=com.iderzheng U=0 sz=1}        Run #6: ActivityRecord{429d5408 u0 com.iderzheng/.SingleInstanceActivity t24}      TaskRecord{42b0ee20 #25 I=com.iderzheng/.SingleTaskActivity U=0 sz=5}        Run #5: ActivityRecord{434c2238 u0 com.iderzheng/.StandardActivity t25}        Run #4: ActivityRecord{42e9e8f8 u0 com.iderzheng/.SingleTopActivity t25}        Run #3: ActivityRecord{42bffdf0 u0 com.iderzheng/.StandardActivity t25}        Run #2: ActivityRecord{42a7e160 u0 com.iderzheng/.SingleTaskActivity t25}      TaskRecord{4282e508 #23 A=com.iderzheng U=0 sz=2}        Run #1: ActivityRecord{429655d8 u0 com.iderzheng/.StandardActivity t23}        Run #0: ActivityRecord{429564e0 u0 com.iderzheng/.MainActivity t23}   ... ... ... ...  Recent tasks:  ... ... ... ...

整个log显示了当前所有在运行的任务栈,它们的id分别是什么。对于每个Task,也有Activity数量等信息,同时也列出了其中的Activity列表,并且对于每个Activity也有比较详细的描述,比如启动它的Intent的内容。

如果觉得内容过多,只想看看栈的内容,也可以直接跳到”Running activities (most recent first)”那部分,比较简洁而又明了的列出了栈中得Activity列表,就能知道当按下返回键的时候会应该会回到哪个Activity以后是要退出程序。

对于”Running activitie”s的内容在dumpsys activity中就有,并不需要dumpsys activity activities,也可以用下边的指令来限制仅输出”Running activities”列表:

adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'

缺点

很明显的看出,使用adb shell的相对于之前的方式的明显好处就是不需要添加额外的代码,而且任务栈的信息也更加详尽。但是同样的它只能输出Activity的类名,对于具体属性没有记录。

adb shell对于调试Android程序有很多的帮助,可惜对于adb指令都没有比较全面详细而又系统的教程。只能靠在实践中慢慢摸索,从网上零星介绍中获得。

Download Source Code for Testing

更多相关文章

  1. Android(安卓)Timer 更好方法
  2. android中webview开启了硬件加速后会出现闪烁问题
  3. Android(安卓)Timer 更好方法
  4. Android(安卓)文件管理器 Android文件管理器源代码
  5. googleMap----放大,缩小,东南西北,四种视图切换代码
  6. android:exported 属性详解
  7. Android应用程序进程启动过程的源代码分析
  8. Android(安卓)中自定义控件和属性(attr.xml,declare-styleable,T
  9. 移动应用开发:如何创建自定义Android代码模板

随机推荐

  1. Android RadioGroup和RadioButton使用
  2. 【Android Training视频系列】第4讲Build
  3. Android所有系统资源图标android.R.drawa
  4. Intent实现Android间的页面跳转
  5. android 开发BUG
  6. Android中事件分发机制分析
  7. Android下基于XML的Graphics shape使用方
  8. 【Android学习入门】Android studio基本
  9. dev android project from cmd
  10. Android google地图开发的前期准备(MD5和