2010-08-04 9 views
19

Informacja: Moje urządzenie to Nexus One z 2.2 i przetestowałem dwa projekty: jeden na 1,5 i jeden na 2.1.Problemy z wykryciem cyklu życia ekranu podczas wyświetlania ekranu:

Problem: rozumiem cykl życia aplikacji po wyłączeniu i włączeniu ekranu.

Oto moje wyjście

// activity starts 
08-04 17:24:17.643: ERROR/PlayActivity(6215): onStart executes ... 
08-04 17:24:17.643: ERROR/PlayActivity(6215): onResume executes ... 
// screen goes off 
08-04 17:24:28.943: ERROR/PlayActivity(6215): onPause executes ... 
08-04 17:24:32.113: ERROR/PlayActivity(6215): onStop executes ... 
08-04 17:24:32.113: ERROR/PlayActivity(6215): onDestroy executes ... 
08-04 17:24:32.983: ERROR/PlayActivity(6215): onStart executes ... 
08-04 17:24:32.983: ERROR/PlayActivity(6215): onResume executes ... 
08-04 17:24:32.983: ERROR/PlayActivity(6215): onPause executes ... 
// screen goes on 
08-04 17:24:47.683: ERROR/PlayActivity(6215): onResume executes ... 
// lock removed 
08-04 17:24:56.943: ERROR/PlayActivity(6215): onPause executes ... 
08-04 17:24:59.663: ERROR/PlayActivity(6215): onStop executes ... 
08-04 17:24:59.663: ERROR/PlayActivity(6215): onDestroy executes ... 
08-04 17:25:00.943: ERROR/PlayActivity(6215): onStart executes ... 
08-04 17:25:00.943: ERROR/PlayActivity(6215): onResume executes ... 

Jestem całkowicie zdezorientowany. Po co ponownie uruchamiać aktywność po uruchomieniu ekranu? I dlaczego zatrzymać i ponownie go uruchomić, gdy ekran był już włączony i usunięto tylko blokadę?

Aby upewnić się, że nie zrobiłem nic złego, stworzyłem nowy projekt z tylko tą aktywnością. Wyjście jest identyczne ...

public class LifeCycleTest extends Activity { 

    private final static String DEBUG_TAG = "FirstLifeLog"; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.e(DEBUG_TAG, "onCreate executes ..."); 
     setContentView(R.layout.main); 
    } 

    protected void onRestart() { 
     super.onRestart(); 
     Log.e(DEBUG_TAG, "onRestart executes ..."); 
    } 

    protected void onStart() { 
     super.onStart(); 
     Log.e(DEBUG_TAG, "onStart executes ..."); 
    } 

    protected void onResume() { 
     super.onResume(); 
     Log.e(DEBUG_TAG, "onResume executes ..."); 
    } 

    protected void onPause() { 
     super.onPause(); 
     Log.e(DEBUG_TAG, "onPause executes ..."); 
    } 

    protected void onStop() { 
     super.onStop(); 
     Log.e(DEBUG_TAG, "onStop executes ..."); 
    } 

    protected void onDestroy() { 
     super.onDestroy(); 
     Log.e(DEBUG_TAG, "onDestroy executes ..."); 
    } 
} 

Czy ktoś ma pomysł?

Aktualizacja od dzisiaj (nie rozumiem, dlaczego nie zachowuje się jak ostatni raz, może więcej wolnych zasobów?)

// activity starts 
08-09 12:14:03.122: ERROR/FirstLifeLog(15406): onCreate executes ... 
08-09 12:14:03.132: ERROR/FirstLifeLog(15406): onStart executes ... 
08-09 12:14:03.132: ERROR/FirstLifeLog(15406): onResume executes ... 
// screen off 
08-09 12:14:07.412: ERROR/FirstLifeLog(15406): onPause executes ... 
// screen on 
08-09 12:14:11.722: ERROR/FirstLifeLog(15406): onResume executes ... 
// no log for removed screen lock 
+0

Co jest dziwne, że widzę naDestroy(), onStart(), onResume(), ale nie widzę żadnych połączeń onCreate(). Jestem również zainteresowany zrozumieniem zachowania. –

+0

To dlatego, że moje narzędzie onCreate nieodebrane w dzienniku ... Również wypróbowałem to jeszcze raz ... teraz moja gra ma to samo zachowanie, ale testproject ma oczekiwane zachowanie (zobacz aktualizację) – WarrenFaith

Odpowiedz

-2

Zobacz Activity Lifecycle dokumentację dla dobrego opisu cyklu, z diagramami.

Najprawdopodobniej twoja aktywność zostanie zabita przy wyłączonym ekranie, aby oszczędzać zasoby (moc baterii). Jak stwierdza dokumentacja, w zasadzie możesz zostać zabity w dowolnym momencie, gdy Android chce uwolnić zasoby. Dlatego zawsze powinieneś zaprojektować swoje działania, aby móc je zatrzymać i zrestartować w dowolnym momencie.

+1

Znam dokumentację cyklu życia. Zabicie w celu oszczędzania zasobów nie może być przyczyną, ponieważ jest natychmiast restartowane. I to jest właśnie mój problem. Nie rozumiem, dlaczego został zabity i natychmiast uruchomiony ponownie. Przechowuję dużo w bazie danych po uruchomieniu funkcji onDestroy() ... Niepotrzebna aplikacja niszczy wyniki w długim czasie odpowiedzi ... – WarrenFaith

+0

Rozumiem ... Nie testowałem tej teorii, ale dokumentacja omawia niektóre configChanges: http://developer.android.com/reference/android/R.attr.html#configZmiany powodujące ponowne uruchomienie aplikacji. Jest możliwe, że włączanie i wyłączanie ekranu mieści się w trybie uiMode? Niezależnie od tego możesz sprawdzić, czy możesz sprawić, że onDestroy będzie bardziej wydajny. Może zapisać stan w całości, więc w tym momencie jest mniej do zapisania? –

0

To właśnie tak. Jeśli czytasz cykl życia aktywności, zobaczysz, że kroki są w ten sposób uporządkowane. To nie tylko wtedy, gdy ekran się włącza i wyłącza, ale także kiedy chnage oreintation telefonu. Android odtworzył działanie, wykonując dokładnie te same kroki, o których wspomniałeś powyżej. Spróbuj obrócić ekran, zobaczysz wtedy! =)

+0

Myślę, że twoje położenie jest bardzo podobne do sytuacji, o której wspomniałem powyżej. Musi mieć coś ze zmienionymi widokami, aby aktywność została zabita i odtworzona, by działała bez ekranu! To tylko moje przypuszczenie ... – Shouvik

30

Miałem ten sam problem z moją własną grą. Moja gra działa tylko w orientacji poziomej, a po wyłączeniu ekranu wygaszacz ekranu z Androidem przejmuje kontrolę (w trybie portretu), wysyłając w ten sposób zmianę orientacji, która niszczy i odtwarza aktywność.

Prostym rozwiązaniem jest stwierdzenie, że uda Ci się zmiany orientacji ekranu:

<activity ... android:configChanges="orientation" ... > 

Jest to dość proste, jeśli działalność jest uznana za jedynie krajobraz (trzeba robić nic), ale można dostać trudniejsze, jeśli aktywność może obracać ...

+0

Dzięki! Prawdopodobnie zabrałbym trochę czasu, żeby to odkryć. Potrafi potwierdzić, co dzieje się z aplikacją Pejzaż: raz odtworzony, aby zmienić portret, ponownie odtwarzany po raz drugi po powrocie z ekranu. Działają również elementy configChanges. To powinno być właściwie (wyraźnie) udokumentowane. – oberstet

+3

To prawdopodobnie powinno być zaprojektowane jako przyjęta odpowiedź, ponieważ chociaż przyszedł miesiąc później identyfikuje przyczynę tego, co pozostało tajemnicze w drugim. –

+0

Czy ktoś wie * jak * wykryć taki cykl życia? Mam na myśli wykrywanie, że onStop jest wywoływany tylko z powodu wyłączania się ekranu i że onStart zostanie wkrótce uruchomiony. – Snicolas

4

Ruben's answer jest całkowicie poprawna, ale tylko jeśli aplikacja skierowana poziom API 12 lub niższy.

Ale ponieważ poziom API 13 oprócz opcji orientation, trzeba zadeklarować opcję screenSize, bo to również zostanie wywołany, gdy urządzenie przełącza pomiędzy pionowym i orientacji poziomej:

<activity ... android:configChanges="orientation|screenSize" ... > 

Inaczej Twoja aktywność będzie nadal odtwarzana przez dodatkowy czas, gdy ekran uruchomi się na interfejsie API 13 lub wyższej platformie.

Zobacz odniesienia do sekcji API docs, android:configChanges.

Powiązane problemy