Rozszerzona Application
klasa może deklarować zmienne globalne. Czy są inne powody?
Rozszerzona Application
klasa może deklarować zmienne globalne. Czy są inne powody?
Odpowiedzi:
Nie mogę wymyślić prawdziwego scenariusza, w którym rozszerzenie Aplikacji jest lepsze od innego podejścia lub konieczne do osiągnięcia czegoś. Jeśli masz drogi, często używany obiekt, możesz go zainicjować w IntentService, gdy wykryjesz, że obiekt nie jest obecnie obecny. Sama aplikacja działa w wątku interfejsu użytkownika, podczas gdy IntentService działa we własnym wątku.
Wolę przekazywać dane z działania do działania z wyraźnymi intencjami lub używać SharedPreferences. Istnieją również sposoby przekazywania danych z fragmentu do jego działania nadrzędnego przy użyciu interfejsów.
"prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences"
. Powinniśmy zawsze eliminować stan globalny tak bardzo, jak tylko możemy i używać standardowych narzędzi Androida do globalnego zarządzania stanem zamiast statycznych zmiennych / singletonów itp.
apk
plik w naszym telefonie komórkowym, składa się on z wielu przydatnych bloków, takich jak, Activity
s, Service
s i inne.Application
niezależnie od tego, z Activity
którego korzysta użytkownik,Application
,Cursor
i zamykanie go wielokrotnie nie jest dobre pod względem wydajności,Intent
s do przekazania danych, ale jest to niezdarne, a sama aktywność może nie istnieć w pewnym scenariuszu, w zależności od dostępności pamięci.Application
,Application
do uruchomienia pewnych rzeczy, takich jak analiza itp., Ponieważ klasa aplikacji jest uruchamiana przed uruchomieniem Activity
s lub
Services
s,Klasa aplikacji to obiekt, który ma pełny cykl życia aplikacji. To twoja najwyższa warstwa jako aplikacja. Przykładowe możliwe zastosowania:
Możesz dodać to, czego potrzebujesz, gdy aplikacja jest uruchamiana, zastępując onCreate w klasie Application.
przechowują zmienne globalne, które przechodzą od działania do działania. Jak Asynctask.
itp
Czasami chcesz przechowywać dane, takie jak zmienne globalne, do których trzeba uzyskać dostęp z wielu działań - czasami wszędzie w aplikacji. W takim przypadku pomoże Ci obiekt Application.
Na przykład, jeśli chcesz uzyskać podstawowe dane uwierzytelniające dla każdego żądania http , możesz zaimplementować metody uwierzytelniania danych w obiekcie aplikacji.
Następnie możesz uzyskać nazwę użytkownika i hasło w dowolnej z takich czynności:
MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();
I na koniec pamiętaj, aby używać obiektu Application jako obiektu pojedynczego:
public class MyApplication extends Application {
private static MyApplication singleton;
public MyApplication getInstance(){
return singleton;
}
@Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
Aby uzyskać więcej informacji, kliknij opcję Klasa aplikacji
Klasa Application to singleton, do którego można uzyskać dostęp z dowolnego działania lub z dowolnego miejsca, w którym znajduje się obiekt Context.
Dostajesz także trochę cyklu życia.
Możesz użyć metody onCreate aplikacji, aby utworzyć wystąpienia drogich, ale często używanych obiektów, takich jak pomocnik analityczny. Wtedy możesz uzyskać dostęp do tych obiektów i korzystać z nich wszędzie.
Najlepsze wykorzystanie klasy aplikacji. Przykład: Załóżmy, że musisz ponownie uruchomić menedżera alarmów po zakończeniu rozruchu.
public class BaseJuiceApplication extends Application implements BootListener {
public static BaseJuiceApplication instance = null;
public static Context getInstance() {
if (null == instance) {
instance = new BaseJuiceApplication();
}
return instance;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onBootCompleted(Context context, Intent intent) {
new PushService().scheduleService(getInstance());
//startToNotify(context);
}
To nie odpowiedź, ale obserwacja : pamiętaj, że dane w rozszerzonym obiekcie aplikacji nie powinny być powiązane z instancją działania, ponieważ możliwe jest, że masz jednocześnie uruchomione dwie instancje tej samej czynności (jedną w pierwszy plan i jeden niewidoczny) .
Na przykład, zaczynasz swoją aktywność normalnie w programie uruchamiającym, a następnie „minimalizujesz” go. Następnie uruchamiasz inną aplikację (np. Tasker), która uruchamia kolejną instancję Twojej aktywności, na przykład w celu utworzenia skrótu, ponieważ Twoja aplikacja obsługuje android.intent.action.CREATE_SHORTCUT. Jeśli następnie utworzony zostanie skrót i to wywołanie działania tworzącego skrót zmodyfikuje dane obiektu aplikacji, to działanie działające w tle zacznie używać tego zmodyfikowanego obiektu aplikacji po przywróceniu go na pierwszy plan.
Widzę, że na to pytanie brakuje odpowiedzi. Rozszerzam, Application
ponieważ używam implementacji Billa Pugh Singleton ( patrz odniesienie ), a niektóre z moich singletonów wymagają kontekstu. Do Application
klasy wygląda następująco:
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private static MyApplication sInstance;
@Contract(pure = true)
@Nullable
public static Context getAppContext() {
return sInstance;
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() called");
sInstance = this;
}
}
A singletony wyglądają tak:
public class DataManager {
private static final String TAG = DataManager.class.getSimpleName();
@Contract(pure = true)
public static DataManager getInstance() {
return InstanceHolder.INSTANCE;
}
private DataManager() {
doStuffRequiringContext(MyApplication.getAppContext());
}
private static final class InstanceHolder {
@SuppressLint("StaticFieldLeak")
private static final DataManager INSTANCE = new DataManager();
}
}
W ten sposób nie muszę mieć kontekstu za każdym razem, gdy używam singletona i uzyskuję leniwą synchronizowaną inicjalizację z minimalną ilością kodu.
Wskazówka: aktualizacja szablonu singleton Android Studio pozwala zaoszczędzić dużo czasu.
Myślę, że możesz używać klasy Application do wielu rzeczy, ale wszystkie one są związane z twoją potrzebą wykonania pewnych czynności PRZED rozpoczęciem jakichkolwiek działań lub usług. Na przykład w mojej aplikacji używam niestandardowych czcionek. Zamiast dzwonić
Typeface.createFromAsset()
z każdego działania, aby uzyskać referencje do moich czcionek z folderu Assets (jest to złe, ponieważ spowoduje to wyciek pamięci, ponieważ zachowujesz odwołanie do zasobów za każdym razem, gdy wywołasz tę metodę), robię to z onCreate()
metody w mojej klasie Application :
private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
super.onCreate();
appInstance = this;
quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
"fonts/Quicksand-Regular.otf");
...
}
Teraz mam również metodę zdefiniowaną w ten sposób:
public static App getAppInstance() {
return appInstance;
}
i to:
public Typeface getQuickSandRegular() {
return quicksandRegular;
}
Tak więc z dowolnego miejsca w mojej aplikacji wszystko, co muszę zrobić, to:
App.getAppInstance().getQuickSandRegular()
Kolejnym zastosowaniem dla mnie klasy Application jest sprawdzenie, czy urządzenie jest podłączone do Internetu PRZED czynnościami i usługami wymagającymi połączenia faktycznie rozpoczną się i podejmą niezbędne działania.
Źródło: https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class
W wielu aplikacjach nie ma potrzeby bezpośredniej pracy z klasą aplikacji. Istnieje jednak kilka dopuszczalnych zastosowań niestandardowej klasy aplikacji:
- Specjalistyczne zadania, które należy wykonać przed utworzeniem pierwszego działania
- Globalna inicjalizacja, która musi być współdzielona przez wszystkie komponenty (raportowanie awarii, trwałość)
- Metody statyczne zapewniające łatwy dostęp do statycznych niezmiennych danych, takich jak udostępniony obiekt klienta sieci
Nigdy nie należy przechowywać danych instancji mutowalnych wewnątrz obiektu Application, ponieważ jeśli założymy, że dane tam pozostaną, aplikacja nieuchronnie ulegnie awarii w pewnym momencie z wyjątkiem NullPointerException. Nie ma gwarancji, że obiekt aplikacji pozostanie w pamięci na zawsze, zostanie zabity. Wbrew powszechnemu przekonaniu aplikacja nie zostanie ponownie uruchomiona od zera. Android utworzy nowy obiekt Application i rozpocznie działanie, w którym użytkownik był wcześniej, dając złudzenie, że aplikacja nigdy nie została zabita.
Możesz uzyskać dostęp do zmiennych dowolnej klasy bez tworzenia obiektów, jeśli jest rozszerzony przez Application. Można je wywoływać globalnie, a ich stan jest utrzymywany, dopóki aplikacja nie zostanie zabita.
Użycie aplikacji rozszerzającej sprawia, że aplikacja jest pewna dla każdego rodzaju operacji, które chcesz przez cały okres jej działania. Teraz może to być dowolny rodzaj zmiennych i przypuśćmy, że jeśli chcesz pobrać jakieś dane z serwera, możesz umieścić swoje asynchroniczne zadanie w aplikacji, aby pobierało się za każdym razem i ciągle, dzięki czemu automatycznie otrzymasz zaktualizowane dane. Użyj tego linku po więcej wiedzy ...
http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android
Aby dodać do innych odpowiedzi stwierdzających, że możesz chcieć przechowywać zmienne w zakresie aplikacji, dla dowolnych długo działających wątków lub innych obiektów, które wymagają powiązania z twoją aplikacją, w której NIE używasz działania (aplikacja nie jest działaniem). na przykład brak możliwości zażądania powiązanej usługi .. wtedy preferowane jest powiązanie z instancją aplikacji. Jedynym oczywistym ostrzeżeniem związanym z tym podejściem jest to, że obiekty żyją tak długo, jak działa aplikacja, więc wymagana jest bardziej niejawna kontrola nad pamięcią, w przeciwnym razie napotkasz problemy związane z pamięcią, takie jak wycieki.
Innym przydatnym może być to, że w kolejności operacji aplikacja jest uruchamiana jako pierwsza przed jakąkolwiek czynnością. W tych ramach czasowych możesz przygotować wszelkie niezbędne czynności porządkowe, które miałyby miejsce przed twoją pierwszą czynnością, jeśli sobie tego życzysz.
2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created