Jedna z moich aplikacji Android używa niestandardowej klasy aplikacji, aby wykonać pewną globalną inicjalizację. To zrobione w metodzie onCreate():

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        someCustomInit();
    }
}

Działa dobrze, ale teraz odkrywam katastrofę zaloguj się w konsoli deweloperskiej, co wskazało, że MyApplication.onCreate() nie ukończył / nie ukończył w momencie wystąpienia katastrofy: kod zawiesiony, ponieważ wykonywane jest {{x1 }} Nie był kompletny.

Jak to możliwe? Zakładałem, że MyApplication.onCreate() uruchomiłby przed wszystkimi innymi kodeksami? Czy to nie jest poprawne?

Czy zapisuje się, aby przenieść someCustomInit(); do konstruktora MyApplication} zamiast tego Nie należy uruchomić innego kodu, zanim obiekt aplikacji został utworzony, poprawny?

Czy są jakieś efekty uboczne z używania konstruktora zamiast onCreate()?

2
Andrei Herford 5 czerwiec 2018, 14:16

3 odpowiedzi

Najlepsza odpowiedź

Zakładałem, że myApplication.oncreate () uruchomi się przed wszystkimi innymi kodeksami? Czy to nie jest poprawne?

ContentProvider Instancje są tworzone przed onCreate() nazywane jest Application. Teoretycznie śledzenie stosu powinno pokazać, jaki kod twojego jest wywoływany przed inicjalizacją.

Czy zapisuje się, aby przenieść SomeCustominit (); do konstruktora myAplikacji zamiast tego?

To zależało od tego, co dzieje się w someCustomInit(). Twój Application nie jest jeszcze inicjowany.

Inną możliwością jest zastąpienie attachBaseContext(), takie jak jak ACRA jest zaczepiona w. Tam, otrzymasz obiekt Context, którego można użyć, jeśli inicjalizacja wymaga Context.

1
CommonsWare 5 czerwiec 2018, 11:23

Jak to jest możliwe?

Jest to możliwe, ponieważ Application klasy onCreate jest wywoływana dla każdego procesu aplikacji.

Na przykład Service można uruchomić w oddzielnym procesie, dzięki czemu aplikacja może zostać uruchomiona dwukrotnie. Spełniłem to zachowanie, gdy używano Yandex.Appmetrica biblioteka. W rzeczywistości nie jest źle, ponieważ awarie w bibliotece nie wpłyną na inne części zastosowania.

Czy są jakieś efekty uboczne z wykorzystaniem konstruktora zamiast onCreate ()?

Z Dokumentacja:

Klasa aplikacji lub podklasa klasy aplikacji, jest tworzona przed inną klasą, gdy zostanie utworzony proces aplikacji / pakietu.

Więc konstruktor zostanie wywołany dwa razy. Jakakolwiek różnica?

Powinieneś przenieść swój kod, który ma biec tylko raz na inny, poza klasy Application. Prawdopodobnie w niektórych Singleton, który zostanie wywołany z Launcher Activity lub smth. Właściwie jeśli zobaczysz Źródła z klasy Application Zobaczysz ten komentarz:

Zwykle nie ma potrzeby aplikacji podklasy. W większości sytuacji statyczne singletony mogą zapewnić tę samą funkcjonalność w sposób bardziej modułowy.

2
Andrey Danilov 5 czerwiec 2018, 11:37

Klasa Application to singleton dla procesu aplikacji, ale jego onCreate() nie jest pierwszym możliwym kodem do wykonania. Inicjalizatory z klasy, konstruktor, jak również dowolne bloki kodu static (często używane do ładowania natywnych libów) będą wykonywać najpierw. Bloki kodu static, w szczególności uruchamiają się, gdy klasa jest ładowana przez środowisko wykonawcze.

Zwykle nie jest to problem, a najbezpieczniejsza trasa jest umieszczenie określonego kodu w metodzie {x0}}.

1
Larry Schiefer 5 czerwiec 2018, 11:27