Wiem, że otrzymuję ten sam wynik w przypadku obu fragmentów kodu
finish();
startActivity(newActivity);
i
startActivity(newActivity);
finish();
Chciałbym poznać Twoją opinię, jeśli jest między nimi duża różnica. Czy jeden jest lepszy od drugiego? Jeśli tak, dlaczego?
Animacja jest wyraźnie inna (przynajmniej od 4.1).
finish()
Pierwsze wywołanie zaczyna zanikać pierwsze działanie wcześniej i możesz przez chwilę zobaczyć czarne tło przed zanikiem nowej czynności. WywołaniestartActivity()
pierwsze zanika w nowej czynności na poprzedniej, a czarne tło nie jest widoczne.źródło
Istnieje ważna różnica w zachowaniu zadań aplikacji w zależności od kolejności
startActivity()
ifinish()
wywołań.Przypadek, który opisuję, dotyczy tylko sytuacji, gdy bieżąca czynność (zatrzymywana) jest jedyną w zadaniu.
Zwykle można by się spodziewać, że zamiar rozpoczęcia (zamiar, który tworzysz, aby rozpocząć inną czynność) nie zostanie zmieniony przez system. I tak nie jest, jeśli
finish()
wywoływana jest ostatnia czynność w zadaniu przed wywołaniemstartActivity()
.W tym przypadku ActivityManager, komponent systemowy, podczas wykonywania flagi
startActivity()
addIntent.FLAG_ACTIVITY_NEW_TASK
do celu.Kiedy tak się dzieje, można zauważyć wpis dziennika w LogCat podobny do tego:
I to jest punkt zwrotny, od którego (w pewnych warunkach) sprawy mogą się nie udać.
Podsumowując, jeśli chcesz być po bezpiecznej stronie (zamiast doświadczać nieoczekiwanych skutków ubocznych
FLAG_ACTIVITY_NEW_TASK
dodania do intencji), to kolejność musi być:startActivity()
finish()
Projekt demonstracyjny .
Nagrania z ekranu:
źródło
Oprócz odpowiedzi Emmanuels:
Obie metody
startActivity
ifinish
zostaną zaplanowane po zakończeniu metody wywołującej, ponieważ obie są przetwarzane przez wątek interfejsu użytkownika.źródło
Zrobiłbym drugi wybór, nie popieram tego na niczym, co wyszukałem w oficjalnych źródłach, ale bardziej sensowne jest rozpoczęcie nowej czynności przed wywołaniem zakończenia, w ten sposób nowa aktywność pojawia się z powodu zamiaru , a działanie w tle teraz może wywołać wszystkie swoje metody czyszczenia.
Gdybyś zrobił to na odwrót, być może zamiar nie będzie miał czasu na odpalenie przed zakończeniem czyszczenia. To znaczy, czy aktywność wywoła startActivity () po wywołaniu finish ()?
Mam nadzieję, że rozumiesz, co próbuję powiedzieć, zrobiłbym drugą opcję, aby być bezpiecznym.
źródło
Miałem podobny problem:
Activity A: singleInstance Activity B: singleInstance Activity C: singleInstance A starts B B starts C C wants to start A:
tutaj, jeśli używam:
finish(); startActivity(A);
dzieje się coś przewodowego: działanie B pojawia się na pierwszym planie zamiast A! ale jeśli zmienię kod w ten sposób:
startActivity(A); finish();
wszystko wydaje się w porządku i widać Aktywność A.
Nie wiem, w czym jest problem, ale wydaje się, że w pierwszym przypadku C kończy się przed wykonaniem polecenia startActivity, tak że tylny stos radzi sobie z sytuacją i pokazuje jego najwyższą aktywność, czyli B! ale w drugim przypadku wszystko dzieje się normalnie.
źródło
Zwykle robię to
startActivity()
wcześniej,finish()
ponieważ myślę, że to upewniłoby się, że nowy ekran pojawi się, zanim poprzedni zgaśnie.Mam stronę logowania w mojej aplikacji. Po pomyślnym zalogowaniu użytkownika aktywność logowania zniknęła, a główna aktywność została zakończona. Działa dobrze w systemie Android 4.
Dzisiaj chciałem przepisać to w Material Design. Jednak mam duży problem. Nowe studio Android tworzy puste zadania z Material Design, które moim zdaniem wymagają wielu zasobów. Ten sam proces, ale wystąpił błąd
11-26 18:20:44.450 18397-18397/? I/Choreographer: Skipped 42 frames! The application may be doing too much work on its main thread. 11-26 18:20:44.485 18397-18408/? I/art: Background partial concurrent mark sweep GC freed 2864(191KB) AllocSpace objects, 4(43MB) LOS objects, 13% free, 100MB/116MB, paused 8.056ms total 39.767ms
Powiedział, że moje aplikacje zajmują wiele zasobów podczas
mainActivity
uruchamiania w moim dzienniku telefonu. Nie mam nicmainActivity
tym, że jest to domyślny układ Material Design.Odwróciłem kolejność i teraz działa bezbłędnie na moim telefonie.
źródło