2014-02-26 9 views
11

Ich habe eine Anwendung, die eine Klasse von der Application-Klasse abgeleitet hat und festgestellt haben, dass seine onCreate() -Methode mehrmals aufgerufen wird. Darüber hinaus wird der Wert seiner statischen Variablen jedes Mal zurückgesetzt, wenn onCreate() aufgerufen wird.statische Variable Reinitialisierung auf M, aber nicht auf L aufgrund der Anwendung onCreate() mehr als einmal aufgerufen

Dieses Verhalten tritt nur bei M auf, es tritt nicht bei L auf. Ich versuche herauszufinden, ob es ein Fehler in M ​​oder eine beabsichtigte Änderung in M ​​ist oder dass ein grundsätzliches Problem mit der App-Architektur vorliegt ruhend und erst jetzt manifestiert mit M.

Die Anwendung abgeleitete Klasse onCreate() wird aufgerufen, wann immer ein Empfänger onReceive() des Broadcasts aufgerufen wird. Mehrere Instanzen der Application-Klasse werden nicht erstellt - onCreate() wird für dieselbe Objektinstanz aufgerufen, und derselbe Anwendungskontext ist durchgängig vorhanden.

Hier einige Code-Schnipsel diese Beobachtung demonstriert:

public class MyApplication extends Application 
{ 
    public static int debugVal = 5; 

    public MyApplication() 
    { 
     theApp = this; 
    } 

    public void onCreate() 
    { 
     Log.v(TAG, "++++++++++++ onCreate() debugVal: " + debugVal); 
     debugVal = 10; 
     .... 



public class MyBroadcastReceiver extends BroadcastReceiver 
{ 
    @Override 
    public void onReceive (Context context, Intent intent) 
    { 
    Log.v(TAG, "onReceive. debugVal: " + MyApplication.debugVal); 
    ... 

Wenn auf Eibisch die logcat Ausgang laufen ist:

831-1412/? I/ActivityManager Start proc 2244:com.company.redacted/u0a86 for broadcast com.company.redacted/com.company.redacted2.MyBroadcastReceiver 
2244-2244/? V/MyApplication: ++++++++++ onCreate() debugVal: 5 
2244-2244/? V/MyBroadcastReceiver: onReceive. debugVal: 10 
... 
831-1327/? I/ActivityManager: Start proc 3271.com.company.redacted/u0a86 for broadcast com.company.redacted2/com.company.redacted1.MyBroadcastReceiver 
3271-3271/? V/MyApplication: +++++++++++ onCreate() debugVal: 5 
.... 

Sehen Sie, wie onCreate() mehr als einmal aufgerufen wird, und wie debugVal hat beim zweiten Aufruf von onCreate() wurde der Wert 10 verloren. Wenn dieselbe .apk auf Lollipop ausgeführt wird, ist der zweite Aufruf von onCreate() nicht vorhanden.

Das Protokoll auf L sieht wie folgt aus:

768-783/? I/ActivityManager: Start proc 2480:com.company.redacted/u0a84 for broadcast com/company.redacted1/com.company.redacted2/MyBroadcastReceiver 
2480-2480/? V/MyApplication: +++++++++++ onCreate() debugVal:5 
2480-2480/? V/MyBroadcastReceiver: onReceive. debugVal: 10 
.... 
2480-2480/com.company.redaced1 v/MyBroadcastReceiver: onReceive. debugVal: 10 

Ich mag gerne wissen, was los ist und zu beseitigen, aber wenn ich nicht ist, kann es die Anwendungsklasse sein würde möglich ersetzen einige Singleton-Klasse, deren statische Variablen garantiert sicher und zuverlässig sind und nur einmal initialisiert werden?

Dies ist eine vorinstallierte App, die beim Booten startet (was eine der Absichten ist, auf die der Empfänger hört) und hat zu diesem Zeitpunkt keine Aktiven.

+0

Was haben Sie kommentiert? Wurden die Broadcast-Empfänger-Protokolle von verschiedenen Prozessen auf L angezeigt? – CurlyCorvus

+0

Ich werde die Protokolle von L in einer Sekunde hinzufügen. Es ist eine große komplexe App, es würde eine Weile dauern, alles zu kodifizieren, was auskommentiert wurde und wahrscheinlich zu viel und zu verwirrend ist, um es zusammenzufassen. – Gruntcakes

+0

Das super.onCreate() ist da, es ist einfach nicht im abgekürzten Code-Snippet, das ich gepostet habe. – Gruntcakes

Antwort

3

Sie sagen onCreate() wird zweimal im selben Prozess aufgerufen, aber das ist wahrscheinlich falsch. Es ist sehr gut möglich, dass Marshmallow aggressiver ist, wenn es darum geht, Ihren Prozess zu beenden, entweder weil weniger Arbeitsspeicher zur Verfügung steht oder aggressiver beim Löschen leerer Pakete ist (siehe this issue für "empty # 17" und docs mentioning CACHED_EMPTY).

Um dies zu verifizieren, machen Sie Ihren Dienst zu einem Vordergrunddienst, indem Sie startForeground mit einer dauerhaften Benachrichtigung aufrufen. Wenn Ihre Probleme verschwinden, bedeutet dies, dass das Betriebssystem Ihren Prozess beendet hat.

Im Allgemeinen sollten Sie sich nicht darauf verlassen, im Hintergrund zu laufen - machen Sie Initialisierungen so faul und feinkörnig wie möglich, und machen Sie Hintergrundoperationen wie Broadcast-Empfänger so billig wie möglich.

0

Beachten Sie, dass in Logmeldungen, die Sie gezeigt haben, der gesamte Prozess neu gestartet wird und onCreate erneut aufgerufen wird. Können Sie beschreiben, was zwischen den beiden Ereignissen passiert, oder welche Details Ihre Anwendung auslöst und was ausgelöst werden kann das Töten des ersten Prozesses und das Beginnen eines neuen?

0

Statische Variablen sind schlecht für den Haltezustand. Der Grund dafür liegt darin, dass statische Variablen nicht über den Lebenszyklus und App-Starts/-Stillstände hinweg bestehen. In der Regel verwenden Sie nur statische Variablen für den konstanten Zustand. Das sind Variablen, die den gleichen Anfangswert haben oder Konstanten sind.

Wenn sich der Wert ändert, sollte er im Speicher wie Prefs gespeichert werden.


Warum erhalten Sie mehrere Aufrufe an OnCreate; Könnten Sie erläutern, welche Art von BroadcastReceiver Sie implementieren?

Es ist möglich, dass eine eingehende Absicht eine Konfigurationsänderung verursachen könnte, die die Anwendung zerstören und neu erstellen würde.