使用Adb shell dumpsys检测Android的Activity任务栈
转载请标明出处:http://blog.csdn.net/xx326664162/article/details/52385720 文章出自:薛瑄的博客
你也可以查看我的其他同类文章,也会让你有一定的收货
谈起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,设置恰当Intent的Flag来使程序达到预期的效果。
使用adb shell指令来查看Activity栈和Fragment栈
Android为开发者提供了adb(Android Debug Bridge),这是非常强大的调试工具。例如:logcat来显示日志记录。dumpsys。dumpsys可以添加不同的参数来指示需要输出哪一类Service的信息。
查看当前Activity :adb shell dumpsys window w | grep name=""
查看当前栈顶的Activity :adb shell dumpsys activity | grep "mFocusedActivity"
查看当前栈顶的Activity的Fragment :adb shell dumpsys activity your.package.name
本来重点来分析下面这个命令:
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=trueauthority=icc... ... ... ...ACTIVITY MANAGER SERVICES (dumpsys activity services)User 0 active services:* ServiceRecord{429f8668 u0 com.android.bluetooth/.hid.HidService}app=nullcreated=-1h44m27s317ms started=false connections=0... ... ... ...ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)Stack #0:Task id #28TaskRecord{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)... ... ... ...
查看activities栈
每一个类别都有一个括号内容,给出了更加详细的指令来查看该类别下更多具体内容。因此再来尝试指令:
adb shell dumpsys activity activities
看到下边的结果:(下面的结果是经过我删减的,可先不用看懂,大概有个印象,结合后面的demo,自己运行这些命令再去观察)
C:\Users\he>adb shell dumpsys activity activities
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):Stack #1:Task id #3241* TaskRecord{3a9c6b59 #3241 I=com.weixinfu.circles/.SingleTaskActivity U=0 sz=1}userId=0 effectiveUid=u0a194 mCallingUid=u0a194 mCallingPackage=com.weixinfu.circlesintent={flg=0x10000000 cmp=com.weixinfu.circles/.SingleTaskActivity}realActivity=com.weixinfu.circles/.SingleTaskActivityautoRemoveRecents=false isPersistable=true numFullscreen=1 taskType=0 mTaskToReturnTo=0rootWasReset=false mNeverRelinquishIdentity=true mReuseTask=falseActivities=[ActivityRecord{2acf5604 u0 com.weixinfu.circles/.SingleTaskActivity t3241}]askedCompatMode=false inRecents=true isAvailable=truelastThumbnail=null lastThumbnailFile=/data/system/recent_images/3241_task_thumbnail.pnghasBeenVisible=true firstActiveTime=1472625076491 lastActiveTime=1472625076491 (inactive f
or 6s)* Hist #0: ActivityRecord{2acf5604 u0 com.weixinfu.circles/.SingleTaskActivity t3241}packageName=com.weixinfu.circles processName=com.weixinfu.circleslaunchedFromUid=10194 launchedFromPackage=com.weixinfu.circles userId=0app=ProcessRecord{3d67e077 1883:com.weixinfu.circles/u0a194}...Task id #3239* TaskRecord{297f7276 #3239 A=com.weixinfu.circles U=0 sz=4}userId=0 effectiveUid=u0a194 mCallingUid=2000 mCallingPackage=nullaffinity=com.weixinfu.circlesintent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x100000
00 cmp=com.weixinfu.circles/.MainActivity}realActivity=com.weixinfu.circles/.MainActivityautoRemoveRecents=false isPersistable=true numFullscreen=4 taskType=0 mTaskToReturnTo=0rootWasReset=false mNeverRelinquishIdentity=true mReuseTask=falseActivities=[ActivityRecord{340043bc u0 com.weixinfu.circles/.MainActivity t3239}, Activity
Record{2396f1b0 u0 com.weixinfu.circles/.StandardActivity t3239}, ActivityRecord{1ed6243f u0 com
.weixinfu.circles/.StandardActivity t3239}, ActivityRecord{552953c u0 com.weixinfu.circles/.Sing
leTopActivity t3239}]askedCompatMode=false inRecents=true isAvailable=truelastThumbnail=android.graphics.Bitmap@3d25031e lastThumbnailFile=/data/system/recent_image
s/3239_task_thumbnail.pnghasBeenVisible=true firstActiveTime=1472625076462 lastActiveTime=1472625076462 (inactive f
or 6s)* Hist #3: ActivityRecord{552953c u0 com.weixinfu.circles/.SingleTopActivity t3239}packageName=com.weixinfu.circles processName=com.weixinfu.circleslaunchedFromUid=10194 launchedFromPackage=com.weixinfu.circles userId=0app=ProcessRecord{3d67e077 1883:com.weixinfu.circles/u0a194}...* Hist #2: ActivityRecord{1ed6243f u0 com.weixinfu.circles/.StandardActivity t3239}packageName=com.weixinfu.circles processName=com.weixinfu.circleslaunchedFromUid=10194 launchedFromPackage=com.weixinfu.circles userId=0app=ProcessRecord{3d67e077 1883:com.weixinfu.circles/u0a194}...* Hist #1: ActivityRecord{2396f1b0 u0 com.weixinfu.circles/.StandardActivity t3239}packageName=com.weixinfu.circles processName=com.weixinfu.circleslaunchedFromUid=10194 launchedFromPackage=com.weixinfu.circles userId=0app=ProcessRecord{3d67e077 1883:com.weixinfu.circles/u0a194}...* Hist #0: ActivityRecord{340043bc u0 com.weixinfu.circles/.MainActivity t3239}packageName=com.weixinfu.circles processName=com.weixinfu.circleslaunchedFromUid=2000 launchedFromPackage=null userId=0...Running activities (most recent first):TaskRecord{3a9c6b59 #3241 I=com.weixinfu.circles/.SingleTaskActivity U=0 sz=1}Run #8: ActivityRecord{2acf5604 u0 com.weixinfu.circles/.SingleTaskActivity t3241}TaskRecord{297f7276 #3239 A=com.weixinfu.circles U=0 sz=4}Run #7: ActivityRecord{552953c u0 com.weixinfu.circles/.SingleTopActivity t3239}Run #6: ActivityRecord{1ed6243f u0 com.weixinfu.circles/.StandardActivity t3239}Run #5: ActivityRecord{2396f1b0 u0 com.weixinfu.circles/.StandardActivity t3239}TaskRecord{19c8ed7b #3240 A=com.weixinfu.circles U=0 sz=1}Run #4: ActivityRecord{34684002 u0 com.weixinfu.circles/.SingleInstanceActivity t3240}TaskRecord{297f7276 #3239 A=com.weixinfu.circles U=0 sz=4}Run #3: ActivityRecord{340043bc u0 com.weixinfu.circles/.MainActivity t3239}TaskRecord{173f2d1c #3235 A=com.android.settings U=0 sz=2}Run #2: ActivityRecord{156f27de u0 com.android.settings/.SubSettings t3235}Run #1: ActivityRecord{3add385d u0 com.android.settings/.Settings t3235}TaskRecord{37bf9f30 #3220 A=com.tencent.mm U=0 sz=2}Run #0: ActivityRecord{6f06dd7 u0 com.tencent.mm/.ui.LauncherUI t3220}mResumedActivity: ActivityRecord{2acf5604 u0 com.weixinfu.circles/.SingleTaskActivity t3241}mLastPausedActivity: ActivityRecord{552953c u0 com.weixinfu.circles/.SingleTopActivity t3239
}Stack #0:Task id #3212* TaskRecord{242fa1d7 #3212 A=com.cyanogenmod.trebuchet U=0 sz=1}...* Hist #0: ActivityRecord{fd0a891 u0 com.cyanogenmod.trebuchet/com.android.launcher3.Launc
her t3212}...Running activities (most recent first):TaskRecord{242fa1d7 #3212 A=com.cyanogenmod.trebuchet U=0 sz=1}Run #0: ActivityRecord{fd0a891 u0 com.cyanogenmod.trebuchet/com.android.launcher3.Launch
er t3212}mLastPausedActivity: ActivityRecord{fd0a891 u0 com.cyanogenmod.trebuchet/com.android.launche
r3.Launcher t3212}mFocusedActivity: ActivityRecord{2acf5604 u0 com.weixinfu.circles/.SingleTaskActivity t3241}mFocusedStack=ActivityStack{1096bbf9 stackId=1, 21 tasks} mLastFocusedStack=ActivityStack{1096
bbf9 stackId=1, 21 tasks}mSleepTimeout=falsemCurTaskId=3241mUserStackInFront={}mActivityContainers={0=ActivtyContainer{0}A, 1=ActivtyContainer{1}A}
上面的结果是执行了下面的操作产生的:
打开StandardActivity
打开StandardActivity
打开SingleTopActivity
打开SingleTaskActivity
打开SingleTopActivity
打开SingleTopActivity
点击返回按钮
返回结果简要分析:
整个log显示了当前所有在运行的任务栈,stack id 、Task id等
每个stack中包含n个Task
Activity实例是存放在Task中的。
一个Hist # 就是Activity的一个实例。
对每个Activity也有比较详细的描述,比如activity实例的hashCode值、启动它的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对于调试Android程序有很多的帮助,可惜对于adb指令都没有比较全面详细而又系统的教程。只能靠在实践中慢慢摸索,从网上零星介绍中获得。
四种启动模式
standard模式 也是activity的默认启动模式。
不论当前 Task栈中有没有 目标activity实例,都会创建一个新的activity实例,放入当前Task栈(最近的非singleInstance模式 的Task栈)
singleTop模式
若当前Task栈的栈顶不是 目标activity实例 ,创建一个新的activity实例,放入当前Task栈(最近的非singleInstance模式 的Task栈)
若当前Task栈的栈顶是 目标activity实例,则复用该activity实例
singleTask模式
若当前Task栈中没有 目标activity实例,则创建新的Task栈,并创建目标activity实例。(Task栈中存放activity的实例)
若当前Task栈中有 目标activity实例,系统会把位于该activity上的所有activity移除Task栈,从而使得目标activity转入栈顶
singleTask模式的activity所在栈,可以接受其他standard模式和singleTop模式的activity实例
singleInstance模式
若所有Task栈中都没有 activity实例,则创建新的Task栈,并创建activity实例。
若存在 目标activity实例,则把activity实例所在的Task栈转到前台
singleInstance模式的activity所在栈,不接受standard模式、singleTop模式、singleTask模式的activity实例。
所以singleInstance模式的activity实例所在栈,永远只有一个activity实例
实现了四种启动模式的demo
原作者的下载地址,不过需要在linux下解压。或者在这里下载
通过ActivityManager获取状态
Android提供了ActivityManger来帮助开发者了解运行期间的状态,通过调用getRunningTasks(int)方法,就可以在得到RunningTaskInfo的列表,其代表着当前Android设备正在运行着的Task。从RunningTaskInfo中又可以进一步得到更多的信息
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> runningTaskInfoList = am.getRunningTasks(10);
for (RunningTaskInfo runningTaskInfo : runningTaskInfoList) {log("id: " + runningTaskInfo.id);log("description: " + runningTaskInfo.description);log("number of activities: " + runningTaskInfo.numActivities);log("topActivity: " + runningTaskInfo.topActivity);log("baseActivity: " + runningTaskInfo.baseActivity.toString());
}
例如文中提供的示例程序中定义了4个具有不同launchMode的Activity,每点击一次菜单栏上得选项就会弹出一个新的Activity(或者将指定Singleton的Activity置前)。
Activity上显示的数字则指示startActivity()被第几次调用时开启了这个Activity。有一些Singleton的会显示多个数字,也表明它是被复用的。
因为在onCreate()方法上放置了上述代码,所以观察log就能发现当前有多少个Task在被执行,每个Task又有多少个Activities。
缺点
必须在程序中注入调试代码,因为要控制在发布时代码必须被清理了。RunningTaskInfo虽然能够告诉我们有多少个Activity保存在其上,但是没有提供完整的列表,只能看到头尾两个Activity。给出的两个Activity的属性:topActivity和baseActivity也只是ComponentName类型,并非真实的Activity对象,因此除了类的名字没有其他更多信息。
参考:使用adb shell dumpsys检测Android的Activity任务栈
使用Adb shell dumpsys检测Android的Activity任务栈相关推荐
- adb shell dumpsys 使用命令和来源
一.概述 adb shell dumpsys 在Android开发中经常要用到,平时都是零碎的积累,用到什么的时候就 记录下来,最近看了一些资料,发现可以汇总所有的命令,当带某个参数的时候,就可以查看 ...
- Android adb shell dumpsys activity broadcasts分析
adb shell dumpsys activity 中的broadcasts信息 通过adb shell dumpsys activity打印中的第二项就是broadcasts信息: ACTIVIT ...
- Android M App休眠 (adb shell dumpsys usagestats)
App休眠 在 Marshmallow 系统,Google 宣布了一个新的功能叫 App 休眠.App 休眠会阻止那些不 常用的 App(几天没有用过的 App)连接网络或者是运行任何程序直至设备充电 ...
- 打印Activity任务栈脚本:adb shell dumpsys activity
#!/bin/bash while [ 1 ] do echo"****************************<-----开始----->*************** ...
- Android内存泄漏查找和解决adb shell dumpsys meminfo packagement
1.通过adb shell dumpsys meminfo packageName来查看内存使用状况 在没有打开应用的情况下,该命令返回的数据是这样的: 2.打开这个应用的MainActivity,再 ...
- adb shell dumpsys activity
1 需求 查询当前运行activity adb shell dumpsys activity | findstr mFocusedApp adb shell dumpsys activity | fi ...
- adb shell dumpsys简单介绍
以下内容来自stack overflow上的一个提问,因为个人英语水平所限,就不翻译了,将主要内容整理如下,方便查阅.简而言之,介绍了如下内容 dumpsys可以用来检测系统的服务信息 列出dumps ...
- adb shell dumpsys package
1 需求 获取手机中声明的所有权限 perm[issions]: dump permissions 获取手机中申请指定权限的所有应用 permission [name ...]: dump decla ...
- android ADB shell 命令启动 android程序
今天用eclipase写了个android程序,主要用到了service.activity.broadcast,在安卓系统手机上调试通过,现在想用ADB shell命令启动这个程序,使达到的效果和在e ...
- adb shell dumpsys 命令 查看内存
android程序内存被分为2部分:native和dalvik,dalvik就是我们平常说的java堆,我们创建的对象是在这里面分配的,而bitmap是直接在native上分配的,对于内存的限制是 n ...
最新文章
- 最新调查:等这一波COBOL程序员退休,很多关键岗位就后继无人了
- 兰州现超级“牛大”碗比腰粗:牛肉面吃出火锅范
- Altium designer原理图导入word文档模糊——终极解决办法
- [导入]LAMP架构下安装Drupal
- Java主线程等待子线程、线程池
- 怎么给没链接的flash加超链接
- 关于socket阻塞与非阻塞情况下的recv、seng、read、write返回值问题
- win7电脑插音响没声音的解决教程--win10专业版
- Docker网络与资源控制
- vue中引入百度地图
- Lambert漫反射模型
- 基于Springboot和Mybatis的文件上传与下载
- 计算机属性没有共享,win10系统本地连接属性里没有共享选项的具体方案
- 抖音小程序实践二:常用权限申请
- Java EE的几个常用框架简介
- 如何进入大数据领域,学习路线是什么?
- 6.1. Inserting Data
- CSS cursor(鼠标状态)属性
- 公安情报指挥一体化合成作战平台建设,指挥调度系统开发
- 基于GEC6818的个人超市购物系统
热门文章
- 一夜没睡,仍然精力充沛——工作规划-2013.07.23
- KNN算法说明以及sklearn 中 neighbors.KNeighborsClassifier参数说明
- teredo服务器文件,可用teredo服务器
- 计算机硕士伊利诺伊大学排名,2020年伊利诺伊大学芝加哥分校排名TFE Times美国最佳计算机科学硕士专业排名第71...
- threejs修改模型旋转轴
- 服务器bios怎么用u盘装系统,如何进入BIOS并用U盘重装系统
- NO.3 微信第三方平台代创建小程序审核发布以及小程序信息(头像,名称,简介)修改 以及微信错误码 返回信息
- udal导mysql_teledb-udal实践分享
- Floating point exception (core dumped)解决
- 编程英语(单词有音标)