【问题标题】:View the Task's activity stack查看任务的活动堆栈
【发布时间】:2011-01-27 09:57:24
【问题描述】:

我刚刚开始开发一个简单的 Android 应用程序,而我还在学习这个平台。

我正在使用带有 ADT 插件 0.9.6 的 Eclipse IDE。

我需要知道是否可以查看与任务关联的Activity 堆栈?

有没有办法通过 DDMS 工具或任何其他技术?

基本上我需要的是能够查看任务的堆栈活动,以确保应用程序按预期运行。

我知道可以通过在Intent 对象中使用标志以及通过<activity> 元素的某些属性在一定程度上控制任务行为。

但是,如果有一种工具——尤其是在调试模式下——可以让开发人员直接看到Activity 堆栈,那就太好了。

【问题讨论】:

标签: android android-activity


【解决方案1】:

从命令行,您可以使用:adb shell dumpsys activity

这要求活动管理器打印其当前状态的转储。第一部分是按任务组织的完整活动历史记录。之后还打印了很多东西,所以你可能需要向上滚动一下才能找到你想要的东西。

这是它的输出示例(具体内容因平台版本而异),显示最重要的任务是与两个活动的联系,而在其后面的启动器与一个活动:

当前活动管理器状态下的活动: * TaskRecord{44d07218 #4 A android.task.contacts} clearOnBackground=true numActivities=2 rootWasReset=true 亲和力=android.task.contacts 意图={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10600000 cmp=com.android.contacts/.DialtactsActivity bnds=[125,640][235,758]} origActivity=com.android.contacts/.DialtactsContactsEntryActivity realActivity=com.android.contacts/.DialtactsActivity lastActiveTime=288203177(14s不活动) * 历史记录 #8:HistoryRecord{44b87a30 com.android.contacts/.ViewContactActivity} packageName=com.android.contacts processName=android.process.acore 启动FromUid=10004 app=ProcessRecord{44c4f348 1168:android.process.acore/10004} 意图 { act=android.intent.action.VIEW dat=content://com.android.contacts/contacts/lookup/144i148.144i461a29500afc8eeb/1927 cmp=com.android.contacts/.ViewContactActivity } frontOfTask=false task=TaskRecord{44d07218 #4 A android.task.contacts} taskAffinity=android.task.contacts realActivity=com.android.contacts/.ViewContactActivity base=/system/app/Contacts.apk/system/app/Contacts.apk 数据=/data/data/com.android.contacts labelRes=0x7f090012 图标=0x7f02006b 主题=0x7f0e0004 stateNotNeeded=false componentSpecified=false isHomeActivity=false configuration={ scale=1.0 imsi=310/4 loc=en_US touch=3 keys=2/1/2 nav=2/2 orien=1 layout=34} resultTo=HistoryRecord{44d174d0 com.android.contacts/.DialtactsContactsEntryActivity} resultWho=favorites resultCode=2 启动失败=假有状态=假冰柱=空 state=RESUMED 停止=false delayResume=false 整理=false keysPaused=false inHistory=true persistent=false launchMode=0 全屏=真可见=真 freezeBeforeDestroy=假 thumbnailNeeded=假空闲=真 waitingVisible=false 现在Visible=true * 历史记录 #7:HistoryRecord{44d174d0 com.android.contacts/.DialtactsContactsEntryActivity} packageName=com.android.contacts processName=android.process.acore 启动FromUid=10004 app=ProcessRecord{44c4f348 1168:android.process.acore/10004} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.contacts/.DialtactsContactsEntryActivity bnds=[125,640][235,758] } frontOfTask=true task=TaskRecord{44d07218 #4 A android.task.contacts} taskAffinity=android.task.contacts realActivity=com.android.contacts/.DialtactsActivity base=/system/app/Contacts.apk/system/app/Contacts.apk 数据=/data/data/com.android.contacts labelRes=0x7f090007 图标=0x7f02006b 主题=0x7f0e0000 stateNotNeeded=false componentSpecified=true isHomeActivity=false configuration={ scale=1.0 imsi=310/4 loc=en_US touch=3 keys=2/1/2 nav=2/2 orien=1 layout=34} launchFailed=false haveState=true icicle=Bundle[mParcelledData.dataSize=4196] 状态=STOPPED 停止=true delayResume=false 整理=false keysPaused=false inHistory=true persistent=false launchMode=2 全屏=真可见=假 freezeBeforeDestroy=假 thumbnailNeeded=假空闲=真 * TaskRecord{44c4ee90 #2 com.android.launcher} clearOnBackground=true numActivities=1 rootWasReset=true 亲和力=com.android.launcher 意图={act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10600000 cmp=com.android.launcher/.Launcher} realActivity=com.android.launcher/.Launcher lastActiveTime=214734838(73483s 不活动) * 历史记录 #6:HistoryRecord{44c4d988 com.android.launcher/.Launcher} packageName=com.android.launcher 进程名=android.process.acore 启动FromUid=0 app=ProcessRecord{44c4f348 1168:android.process.acore/10004} 意图 { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher/.Launcher } frontOfTask=true task=TaskRecord{44c4ee90 #2 com.android.launcher} taskAffinity=com.android.launcher realActivity=com.android.launcher/.Launcher base=/system/app/Launcher.apk/system/app/Launcher.apk 数据=/data/data/com.android.launcher labelRes=0x7f0a0000 图标=0x7f020015 主题=0x103005f stateNotNeeded=true componentSpecified=false isHomeActivity=true configuration={ scale=1.0 imsi=310/4 loc=en_US touch=3 keys=2/1/2 nav=2/2 orien=1 layout=34} launchFailed=false haveState=true icicle=Bundle[mParcelledData.dataSize=5964] 状态=STOPPED 停止=true delayResume=false 整理=false keysPaused=false inHistory=true persistent=false launchMode=2 全屏=真可见=假 freezeBeforeDestroy=假 thumbnailNeeded=假空闲=真

【讨论】:

  • 有没有一种很好的方法可以通过 logcat 显示当前应用程序的所有任务和活动堆栈?我们真的需要解析 adb 命令吗?
  • 此外,如果您只想查看堆栈中的活动名称,您可以这样做:adb shell dumpsys activity | grep -i run.
  • 很好的答案!我写了一个convenience script,它过滤输出以获取给定包的任务/活动。
  • 除了adb shell dmpsys activity,您还可以获得每个列表,例如adb shell dmpsys activity activities 用于包含主堆栈、运行活动和最近任务的活动管理器活动。dumpsys activity intents 用于未决意图; dumpsys activity broadcasts 为广播状态; dumpsys activity providers 内容提供者; dumpsys activity services 服务; dumpsys activity processes 用于正在运行的进程。
  • @SuryaWijayaMadjid 的命令可以在一行中完成:adb shell dumpsys activity | grep -i run,或adb shell dumpsys activity activities | grep -i run 以获得更清晰的输出。
【解决方案2】:

您可以在命令行中使用以下命令查看系统中的任务和backstacks:

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

或者你可以试试TaskLogger,这是我创建的一个简单的工具,可以监控你App中的所有活动和任务,并在Logcat中实时输出。

【讨论】:

  • +1 .... 我已经尝试过您的 TaskLogger,它是一个很好的工具,对我有很大帮助,但会打印大量不需要的日志。
【解决方案3】:

如果你想检查一个特定包的任务栈,下面的命令就可以了:

adb shell dumpsys activity activities | grep PACKAGE_NAME | grep Hist

【讨论】:

    【解决方案4】:

    我知道这是一个老问题,但是这个功能现在已经融入了 Android Studio:

    然后在生成的文本文件中,搜索ACTIVITY(全部大写):

    【讨论】:

    • 我认为这个选项不再存在,因为 Android Studio 3.0 中新的 Android Profiler 窗口取代了 Android Monitor 工具。
    • 我为这个缺失的函数创建了问题:issuetracker.google.com/issues/77944626 所以请投票给它。谢谢
    【解决方案5】:

    我总是检查这部分长转储消息..

      Running activities (most recent first):
    TaskRecord{4307f828 #56 A com.demo.proj U 0}
      Run #4: ActivityRecord{425a6838 com.demo.proj/com.demo.proj.Activity2}
      Run #3: ActivityRecord{427dc860 com.demo.proj/com.demo.proj.Activity1}
      Run #2: ActivityRecord{420cba18 com.demo.proj/com.demo.proj.MainActivity}
    TaskRecord{430341d0 #2 A com.lge.launcher2 U 0}
      Run #1: ActivityRecord{41e0af68 com.lge.launcher2/.Launcher}
    TaskRecord{44e26ce0 #18 A com.lge.appbox.client U 0}
      Run #0: ActivityRecord{41e9dbe8 com.lge.appbox.client/.AppBoxClient}
    

    注意:运行#4 是您现在在屏幕上看到的活动。 :)

    【讨论】:

    • 什么是“长转储消息”?
    • @MarianPaździoch "adb shell dumpsys activity" 向我们显示了太长的消息。上面的这些消息是其中的一部分。顺便说一句,我有一个小费可以避免这种情况。运行这个,“adb shell dumpsys 活动活动”您可以看到更短的消息,并且可以更轻松地阅读有关活动堆栈的信息。 :)
    • ...如果该列表仍然太长,请打开“最近使用的应用程序”列表并扫掉一些任务。
    【解决方案6】:

    【讨论】:

      【解决方案7】:

      查看近期任务列表

      adb shell dumpsys activity recents
      

      查看正在运行的服务列表

      adb shell dumpsys activity services
      

      对于当前内容提供者的列表

      adb shell dumpsys activity providers
      

      广播状态列表

      adb shell dumpsys activity broadcasts
      

      Pending Intents 列表

      adb shell dumpsys activity intents
      

      权限列表

      adb shell dumpsys activity permissions
      

      【讨论】:

      • 如果你喜欢更多的 GUI-sh 方式,你可以使用 AdbCommander 插件并将这些命令添加到 macros 选项卡中
      【解决方案8】:

      您可以使用工具 hierarchyviewer.bat。它是 android SDK 的一部分。它只适用于模拟器。但它更舒适,更清晰。

      编辑:我刚刚在 Eclipse 中找到了层次结构查看器!它也适用于真实设备。只需打开透视图 Windows->Open Perspective-> Hierarchy View 在列表中,您可以看到所有连接的设备和模拟器以及活动堆栈。此外,在树视图中,您还可以看到有关视图本身的更多信息。

      编辑: 层次结构查看器仅适用于开发人员设备。出于安全原因,生产设备无法做到这一点。更多信息请查看following answer

      【讨论】:

      • Hierarchy Viewer 用于查看活动的 View 层次结构。问题是关于task/activity stack
      【解决方案9】:

      解决方案:“adb shell dumpsys 活动”不适用于 TabActivity。 当每个选项卡项被选中时,相应的活动将被启动。但是当使用 'adb shell dumpsys activity' 它总是返回 'main' 活动:

      public class main extends TabActivity {
          /** Called when the activity is first created. */
          @Override
          public void onCreate(Bundle savedInstanceState) {
              Log.e("xyz", "start main...............");
              super.onCreate(savedInstanceState);
              setContentView(R.layout.main);
      
              Resources res = getResources(); // Resource object to get Drawables
              TabHost tabHost = getTabHost();  // The activity TabHost
              TabHost.TabSpec spec;  // Resusable TabSpec for each tab
              Intent intent;  // Reusable Intent for each tab
      
              // Create an Intent to launch an Activity for the tab (to be reused)
              intent = new Intent().setClass(this, widgets.class);
              spec = tabHost.newTabSpec("Widgets").setIndicator("Widgets", res.getDrawable(R.drawable.tab1)).setContent(intent);
              tabHost.addTab(spec);
      
              intent = new Intent().setClass(this, layouts.class);
              spec = tabHost.newTabSpec("Layouts").setIndicator("Layouts",res.getDrawable(R.drawable.tab2)).setContent(intent);
              tabHost.addTab(spec);
      
              intent = new Intent().setClass(this, composite1.class);
              spec = tabHost.newTabSpec("Composite").setIndicator("Composite",res.getDrawable(R.drawable.tab3)).setContent(intent);
              tabHost.addTab(spec);
      
              intent = new Intent().setClass(this, imageMedia.class);
              spec = tabHost.newTabSpec("Image_Media").setIndicator("Image&Media",res.getDrawable(R.drawable.tab4)).setContent(intent);
              tabHost.addTab(spec);
      
              intent = new Intent().setClass(this, timeDate.class);
              spec = tabHost.newTabSpec("Time_Date").setIndicator("Time&Date",res.getDrawable(R.drawable.tab5)).setContent(intent);
              tabHost.addTab(spec);
      
              intent = new Intent().setClass(this, transitions.class);
              spec = tabHost.newTabSpec("Transitions").setIndicator("Transitions",res.getDrawable(R.drawable.tab6)).setContent(intent);
              tabHost.addTab(spec);
      
              intent = new Intent().setClass(this, advanced.class);
              spec = tabHost.newTabSpec("Advanced").setIndicator("Advanced",res.getDrawable(R.drawable.tab7)).setContent(intent);
              tabHost.addTab(spec);
      
              intent = new Intent().setClass(this, others.class);
              spec = tabHost.newTabSpec("Others").setIndicator("Others",res.getDrawable(R.drawable.tab8)).setContent(intent);
              tabHost.addTab(spec);
      
              intent = new Intent().setClass(this, Dynamic.class);
              spec = tabHost.newTabSpec("Dynamic").setIndicator("Dynamic",res.getDrawable(R.drawable.tab2)).setContent(intent);
              tabHost.addTab(spec);
      
              tabHost.setCurrentTab(0);
      
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-05-22
        • 1970-01-01
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多