Wyświetl stos aktywności zadania


138

Właśnie zacząłem tworzyć prostą aplikację na Androida, wciąż ucząc się platformy.

Używam Eclipse IDE z wtyczką ADT 0.9.6.

Muszę wiedzieć, czy można wyświetlić Activitystos skojarzony z zadaniem?

Czy jest jakiś sposób przez narzędzie DDMS lub jakąkolwiek inną technikę?

Zasadniczo potrzebuję zobaczyć aktywność stosu zadania, aby upewnić się, że aplikacja zachowuje się zgodnie z oczekiwaniami.

Wiem, że można w pewnym stopniu kontrolować zachowanie zadania poprzez użycie flag w Intentobiekcie i poprzez niektóre atrybuty <activity>elementu.

Jednak byłoby miło mieć coś w rodzaju narzędzia - szczególnie w trybie debugowania - które pozwoliłoby programistom zobaczyć Activitystos bezpośrednio do przodu.


Jeśli używasz Android Studio, zamieściłem rozwiązanie [tutaj] [1]. [1]: stackoverflow.com/a/22392616/1798991
Nebu

Odpowiedzi:


164

Z wiersza poleceń możesz użyć: adb shell dumpsys activity

To prosi menedżera aktywności o wydrukowanie zrzutu jego aktualnego stanu. Pierwsza część to pełna historia działań, uporządkowana według zadań. Następnie jest drukowanych wiele rzeczy, więc może być konieczne przewinięcie w górę, aby znaleźć to, czego chcesz.

Oto przykład jego danych wyjściowych (dokładna zawartość różni się w różnych wersjach platformy), pokazując, że głównym zadaniem są kontakty z dwoma działaniami, a za nim program uruchamiający z jednym działaniem:

Działania w obecnym stanie Menedżera działań:
  * TaskRecord {44d07218 # 4 A android.task.contacts}
    clearOnBackground = true numActivities = 2 rootWasReset = true
    affinity = android.task.contacts
    intent = {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 (nieaktywne przez 14 s)
    * Hist # 8: HistoryRecord {44b87a30 com.android.contacts / .ViewContactActivity}
        packageName = com.android.contacts processName = android.process.acore
        launchFromUid = 10004 app = ProcessRecord {44c4f348 1168: android.process.acore / 10004}
        Zamiar {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 / data / com.android.contacts
        labelRes = 0x7f090012 icon = 0x7f02006b theme = 0x7f0e0004
        stateNotNeeded = false componentSpecified = false isHomeActivity = false
        konfiguracja = {scale = 1.0 imsi = 310/4 loc = en_US touch = 3 klawisze = 2/1/2 nav = 2/2 orien = 1 layout = 34}
        resultTo = HistoryRecord {44d174d0 com.android.contacts / .DialtactsContactsEntryActivity} resultWho = ulubione resultCode = 2
        launchFailed = false haveState = false icicle = null
        stan = WZNOWIONO zatrzymany = fałszywy opóźnionyResume = fałszywy wykończenie = fałsz
        keysPaused = false inHistory = true persistent = false launchMode = 0
        fullscreen = true visible = true frozenBeforeDestroy = false thumbnailNeeded = false idle = true
        waitVisible = false nowVisible = true
    * Hist # 7: HistoryRecord {44d174d0 com.android.contacts / .DialtactsContactsEntryActivity}
        packageName = com.android.contacts processName = android.process.acore
        launchFromUid = 10004 app = ProcessRecord {44c4f348 1168: android.process.acore / 10004}
        Zamiar {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 / data / com.android.contacts
        labelRes = 0x7f090007 icon = 0x7f02006b theme = 0x7f0e0000
        stateNotNeeded = false componentSpecified = true isHomeActivity = false
        konfiguracja = {scale = 1.0 imsi = 310/4 loc = en_US touch = 3 klawisze = 2/1/2 nav = 2/2 orien = 1 layout = 34}
        launchFailed = false haveState = true icicle = Bundle [mParcelledData.dataSize = 4196]
        state = STOPPED stop = true delayedResume = false finish = false
        keysPaused = false inHistory = true persistent = false launchMode = 2
        fullscreen = true visible = false frozenBeforeDestroy = false thumbnailNeeded = false idle = true
  * TaskRecord {44c4ee90 # 2 A com.android.launcher}
    clearOnBackground = true numActivities = 1 rootWasReset = true
    affinity = com.android.launcher
    intent = {act = android.intent.action.MAIN cat = [android.intent.category.HOME] flg = 0x10600000 cmp = com.android.launcher / .Launcher}
    realActivity = com.android.launcher / .Launcher
    lastActiveTime = 214734838 (nieaktywne przez 73483 s)
    * Hist # 6: HistoryRecord {44c4d988 com.android.launcher / .Launcher}
        packageName = com.android.launcher processName = android.process.acore
        launchFromUid = 0 app = ProcessRecord {44c4f348 1168: android.process.acore / 10004}
        Zamiar {act = android.intent.action.MAIN cat = [android.intent.category.HOME] flg = 0x10000000 cmp = com.android.launcher / .Launcher}
        frontOfTask = true task = TaskRecord {44c4ee90 # 2 A com.android.launcher}
        taskAffinity = com.android.launcher
        realActivity = com.android.launcher / .Launcher
        base = / system / app / Launcher.apk / system / app / Launcher.apk data = / data / data / com.android.launcher
        labelRes = 0x7f0a0000 icon = 0x7f020015 theme = 0x103005f
        stateNotNeeded = true componentSpecified = false isHomeActivity = true
        konfiguracja = {scale = 1.0 imsi = 310/4 loc = en_US touch = 3 klawisze = 2/1/2 nav = 2/2 orien = 1 layout = 34}
        launchFailed = false haveState = true icicle = Bundle [mParcelledData.dataSize = 5964]
        state = STOPPED stop = true delayedResume = false finish = false
        keysPaused = false inHistory = true persistent = false launchMode = 2
        fullscreen = true visible = false frozenBeforeDestroy = false thumbnailNeeded = false idle = true

czy istnieje dobry sposób na pokazanie wszystkich zadań i działań bieżącej aplikacji za pośrednictwem logcat? czy naprawdę musimy przeanalizować polecenie adb?
programista Androida

85
Ponadto, jeśli chcesz zobaczyć tylko nazwę działań na stosie, możesz to zrobić: adb shell <enter> dumpsys activity | grep -i run .
Surya Wijaya Madjid

6
Świetna odpowiedź! Napisałem wygodny skrypt, który filtruje dane wyjściowe w celu pobrania zadań / czynności dla danego pakietu.
sschuberth

5
dodatkowo adb shell dmpsys activitymożesz uzyskać dla każdej listy, na przykład, adb shell dmpsys activity activitiesAKTYWNOŚCI MENEDŻERA AKTYWNOŚCI, która zawiera stos główny, Uruchomione działania i Ostatnie zadania. dumpsys activity intentsdla oczekujących zamiarów; dumpsys activity broadcastsdla stanu nadawania; dumpsys activity providersdla dostawców treści; dumpsys activity servicesza usługi; dumpsys activity processesdo uruchomionych procesów.
Fredrick Gauss

1
Polecenie @ SuryaWijayaMadjid można wykonać w jednej linii: adb shell dumpsys activity | grep -i runlub adb shell dumpsys activity activities | grep -i rundla nieco czystszego wyniku.
vaughandroid

58

Możesz użyć następującego polecenia w wierszu poleceń, aby wyświetlić zadania i stosy w systemie:

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

Możesz też wypróbować TaskLogger , proste narzędzie, które stworzyłem, które może monitorować wszystkie działania i zadania w Twojej aplikacji i wyświetlać je w Logcat w czasie rzeczywistym.


+1 .... Wypróbowałem Twój TaskLogger, jest to dobre narzędzie i bardzo mi pomaga, ale wyświetla lawinę niechcianych logów.
ThinkDeep,

34

Wiem, że to stare pytanie, ale ta funkcja jest teraz wprowadzona do Android Studio:

zrzut ekranu Android Studio

Następnie w wynikowym pliku tekstowym wyszukaj ACTIVITY(wszystkie litery):

Zrzut ekranu pliku tekstowego Android Studio


20
Myślę, że ta opcja już nie istnieje, ponieważ nowe okno Android Profiler w Android Studio 3.0 zastępuje narzędzia Android Monitor.
Owoc

5
Utworzyłem problem dla tej brakującej funkcji: issuetracker.google.com/issues/77944626, więc zagłosuj na niego. Dzięki
mtrakal

27

Jeśli chcesz sprawdzić stos zadań określonego pakietu, zrobi to następujące polecenie:

adb shell dumpsys activity activities | grep PACKAGE_NAME | grep Hist

12

Zawsze sprawdzam tę część długich wiadomości zrzutu.

  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}

Uwaga: Bieg # 4 to aktywność, którą widzisz teraz na ekranie. :)


2
Co to są „długie wiadomości zrzutu”?
Marian Paździoch

2
@ MarianPaździoch „adb shell dumpsys activity” pokazuje nam zbyt DŁUGIE komunikaty. Ta wiadomość powyżej to trochę z nich. Przy okazji, mam wskazówkę, jak tego uniknąć. Uruchom to, „adb shell zrzuca działania aktywności”. Możesz zobaczyć krótszy komunikat i łatwiej czytać o stosie aktywności. :)
cmcromance

1
... a jeśli ta lista jest nadal za długa, otwórz listę Ostatnie aplikacje i odsuń niektóre zadania.
Barry Fruitman

10

Możesz użyć narzędzia hierarchyviewer.bat. Jest częścią Android SDK. Działa jednak tylko z emulatorem. Ale jest znacznie wygodniejszy i wyraźniejszy.

Edycja: właśnie znalazłem przeglądarkę hierarchii w Eclipse! Działa również z prawdziwymi urządzeniami. Wystarczy otworzyć perspektywę Windows-> Otwórz perspektywę-> Widok hierarchii Na liście możesz zobaczyć wszystkie podłączone urządzenia i emulatory oraz stos aktywności. Ponadto w widoku drzewa można zobaczyć znacznie więcej informacji o samym widoku.

Edycja: Przeglądarka hierarchii będzie działać tylko na urządzeniach programistów. Urządzenia produkcyjne nie mogą tego zrobić ze względów bezpieczeństwa. Aby uzyskać więcej informacji, zapoznaj się z następującą odpowiedzią


4
Przeglądarka hierarchii służy do przeglądania hierarchii widoków działania. Pytanie dotyczyło stosu zadań / działań .
Jeremy Logan,

8

Aby uzyskać listę ostatnich zadań

adb shell dumpsys activity recents

Aby wyświetlić listę uruchomionych usług

adb shell dumpsys activity services

Aby zapoznać się z listą obecnych dostawców treści

adb shell dumpsys activity providers

Aby wyświetlić listę stanu Broadcast

adb shell dumpsys activity broadcasts

Lista oczekujących intencji

adb shell dumpsys activity intents

Aby uzyskać listę uprawnień

adb shell dumpsys activity permissions

Jeśli lubisz bardziej GUI-sh, możesz użyć AdbCommanderwtyczki i dodać te polecenia w macroszakładce
prot0n


1

Rozwiązanie: 'adb shell dumpsys activity' nie działa z TabActivity. Po wybraniu każdej pozycji na karcie zostanie uruchomiona odpowiednia czynność. Ale kiedy używasz `` adb shell dumpsys activity '', zawsze zwraca `` główną '' aktywność:

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);

    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.