Talking about the development of Android program, we need to understand its four main components: Activity, Service, ContentProvider, Broadcastreceiver. The activity is the only direct control interface rendering, facing the user operation of the component (of course browadcastreceiver can also be through the desktop control (App Widgets) to show a limited interface). Android has strict lifecycle control over activity to restrict developers from putting the right code in the appropriate callback function. Android also has very good management and smooth switching for multiple activity conversions, and Android also introduces the concept of task stack, a concept that is extremely important for returning keys on Android devices.
(Most documents describe it as the tasks and back stack, but from the official documentation, Android's task-related tasks are treated as a Stack that holds activities, so it's called a task The stack is not too. )
When you declare the activity you want to use in the Androidmanifest, you can set a different launchMode
activity to get the "start" effect. When using the startActivity
new activity, the incoming intent can also set different flags to achieve different effects. On the other hand, it may turn on another activity when the activity starts, or the function is called to finish()
end the activity.
This makes the activity stack impossible to master, sometimes pressing the back button or clicking close the current activity does not know that the Android system will take the program to the activity, not sure whether this is the last activity to exit the entire program. Also, some buttons and operation loops generate activity and cause memory bloat. For these problems, if you can know the current task stack during debugging, it is convenient to observe and identify the cause of the problem, and then choose the correct launchMode
, set up Intent
the appropriate Flag
program to achieve the desired effect.
Get status through Activitymanager
Android provides activitymanger to help developers understand the state of the runtime, by invoking a getRunningTasks(int)
method that is available on the RunningTaskInfo
list, which represents the task that is currently running on the Android device. Further information can be obtained from the runningtaskinfo.
- Activitymanager am = (Activitymanager) getsystemservice(Context. Activity_service);
- List<runningtaskinfo> Runningtaskinfolist = am. Getrunningtasks(ten);
- 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());
- }
For example, 4 activity with different Launchmode
is defined in the sample program provided in this article. Each time you click on the menu bar, a new activity will pop up (or the activity of the specified singleton will be placed in front of it). The number shown on the
activity indicates that startactivity ()
was activated when the first call was made to the activity. There are some singleton that show multiple numbers and also indicate that it is being reused.
Because the above code is placed on the onCreate ()
method, observing log will reveal how many tasks are currently being executed, and how many activities each task has.
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/c Om.iderzheng.standardactivity}d/ider (3700): baseactivity:componentinfo{com.iderzheng/ Com.iderzheng.singletaskactivity}d/ider (3700):---------------------D/ider (3700): Id:24d/ider (3700): DESCR Iption:nulld/ider (3700): Number of Activities:1d/ider (3700): Topactivity:componentinfo{com.iderzheng/com.ider Zheng. Singleinstanceactivity}d/ider (3700): baseactivity:componentinfo{com.iderzheng/ Com.iderzheng.singleinstanceactivity}d/ider (3700):---------------------D/ider (3700): Id:23d/ider (3700): D Escription: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.and Roid.launcher2.launcher}d/ider (3700): baseactivity:componentinfo{com.android.launcher/ Com.android.launcher2.Launcher}
Disadvantages
You must inject debug code into your program because you want to control that your code must be cleaned up at the time of publication. Runningtaskinfo can tell us how many of the activity was saved on it, but did not provide a complete list, only to see the top two activity. Given the properties of the two activity: topactivity and baseactivity are just componentname types, not real activity objects, so there is no more information than the class name.
Manually record and manage activities stacks
Activity creation and destruction will have a corresponding callback function: onCreate()
, onDestroy()
. Therefore, a static global object can be built Stack
, at which onCreate()
point the current Activity object is added to and Stack
onDestroy()
removed from the stack. So that we can always know the details of the current activity.
Disadvantages
For all activity onCreate()
and methods to onDestroy()
have a corresponding way to and from the stack, either have a unified base class, or force each activity to add the code, but neither of the two approaches are perfect. It is also difficult to emulate singleTask
this kind of creation of a new task, this time using one Stack
is not enough, to consider all the situation is not likely. And as with Activitymanager, the code should only appear in the Debug phase.
Using ADB shell directives
Android also provides the ADB (Android debug Bridge) for developers, which is a very powerful debugging tool. The most common natural is the Logcat to display the log records. Another very powerful directive is the one that is to be mentioned here dumpsys
. dumpsys
You can also add different parameters to indicate what type of service you need to output. For the content mentioned in this article, it is necessary to check that the activity
instructions are:
ADB shell Dumpsys Activity
By entering the instructions above, you can get a very long message about the device, and you can clearly see that they are more detailed categories.
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.int Ent.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.syste Mui.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.androi D.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, + non-act at 3, non-svc at 3): PERS #27: Sys f//P trm:0 605:SYSTEM/10 XX (fixed) ......
Each category has a bracketed content, and more detailed instructions are given to see more specific content under that category. So try the instructions again:
DB Shell Dumpsys activity activities
You can see the results below
Ctivity MANAGER Activities (Dumpsys activity Activities) Stack #0: Task ID #28 * taskrecord{43525058 #28 A=com.andr Oid.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: Activityrecor d{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: Activ Ityrecord{428d1ae8 u0 com.android.systemui/.recent. Recentsactivity T28} taskrecord{429a35f8 #1 a=com.android.launcher u=0 sz=1} Run #0: activityrecord{429a1760 U 0 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=5Rootwasreset=false userid=0 mtasktype=0 numfullscreen=5 montopofhome=trueintent={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=622973 5 (Inactive for 357s) * Hist #4: Activityrecord{4279d2d8 u0com.iderzheng/. SingletopactivityT25} Packagename=com.iderzheng Processname=com.iderzheng launchedfromuid=10124 launchedfrompackage=com.i Derzheng 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 StateN Otneeded=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 STA te=resumed stopped=false delayedresume=false finishing=false keyspaused=false inhistory=true visible=true sleepin G=false idle=true fullscreen=true nodisplay=false immersive=false launchmode=1 frozenbeforedestroy=false Thumbnailneeded=false Forcenewconfig=false Mactivitytype=application_activity_type Thumbholder:42b0ee2 0 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 Co m.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 C om.iderzheng/. Standardactivity T23} Run #0: Activityrecord{429564e0 u0 com.iderzheng/. Mainactivity t23} ...... Recent tasks: ......
The entire log shows all the currently running task stacks, and what their id
differences are. For each task, there is also information such as the number of activity, as well as a list of activity lists, and a more detailed description of each activity, such as the content of the intent that initiated it.
If you feel too much content, just want to see the contents of the stack, you can also jump directly to the "Running activities (most recent first)" That part, a relatively concise and clear listing of the list of activity in the stack, You will be able to know which activity you should return to when you press the return key to exit the program.
For the content of "Running Activitie" s dumpsys activity
, there is no need dumpsys activity activities
, or you can use the following instruction to limit the output of only the "Running activities" list:
'/running activities/,/run #0/P '
Disadvantages
Obviously, the obvious benefit of using the adb shell
method relative to the previous one is that there is no need to add additional code, and the information on the task stack is more detailed. But the same can only output the activity's class name, which is not recorded for specific properties.
adb shell
For debugging Android programs have a lot of help, unfortunately for the ADB directive there is no more comprehensive and systematic tutorial. Can only rely on the practice of slowly groping, from the online sporadic introduction to get.
Download Source Code for testing
References:
- Android Debug Bridge | Android Developers
- How to know which activities is running in Android | The skiing cube
- Wrightrocket:using Dumpsys commands in the Android adb shell
- Activity–how to find back stacks activities in an Android application? –stack Overflow
- What ' s Android ADB shell ' dumpsys ' tool and it's benefits? –stack Overflow
Detect Android's activity task stack using ADB shell Dumpsys