2009-07-01 15 views
13

Ich habe eine Anwendung erstellt, die Kamera verwendet und während der Appplication-Ausführung ist der Bildschirm immer eingeschaltet.Android: Wie Ressourcen freigegeben werden, wenn die Anwendung beendet wird?

Im onCreate() -Methode hinzugefügt ich das Schloss:

final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); 
this.mWakeLock.acquire(); 

Und das ist die überschriebenen OnStop() -Methode:

@Override 
protected void onStop() { 

    if(mWakeLock.isHeld()) 
    { 
     mWakeLock.release(); 
    } 

    super.onStop(); 
} 

Aber nach der Beendigung der Anwendung bleibt der Bildschirm auf die ganze Zeit und wenn ich die Kameraanwendung starte, stößt sie auf einen Fehler, der offensichtlich erscheint, weil die Kameraressourcen nicht freigegeben sind.

Kann jemand alle Ressourcen auf Anwendungsterminierung freigeben?

Antwort

13

Ich würde das Schloss von OnCreate() zu OnResume() verschieben. Sie möchten die Sperre während der sichtbaren Lebensdauer der Aktivität, nicht während der gesamten Lebensdauer der Aktivität. Deine Aktivität könnte definitiv noch laufen, während eine andere Aktivität vor ihr läuft.

Ich würde die Freigabe auf verschieben. OnPause() ist der früheste Punkt, an dem Ihre Anwendung normalerweise vom Betriebssystem beendet werden sollte.

Zusätzlich würde ich nicht überprüfen, ob ich das Schloss vor der Freigabe habe. Wenn Sie OnResume() verwenden, um die Sperre zu erwerben; isHeld sollte in immer wahr sein.

+1

Ihr Vorschlag für nicht für Verriegelungszustand Überprüfung ist in Ordnung, wenn Release() ist ein idempotent Betrieb. Wenn nicht, ist es schlecht. Was, wenn die App die Sperre nicht erhalten konnte und die App schließen möchte? – Thushan

+1

Großer Kommentar. Ich schaute auf den Android-Quellcode. Es sieht so aus, als ob die einzige Möglichkeit, eine Sperre zu erhalten, darin besteht, wenn Sie Ihren Anruf falsch formulieren. In diesem Fall wird ein Fehler protokolliert, es wird jedoch keine Ausnahme ausgelöst. Wenn Sie release() aufrufen, ohne eine Sperre zu erhalten, wird eine Ausnahme "WakeLock underlocked" ausgelöst. Die Dokumentation von acquire() führt dazu, dass man denkt, wenn man nach dem Schloss fragt, bekommt man das Schloss. Aber wenn Sie das überprüfen sollten, dann sollten Sie direkt nach dem acquire() überprüfen, nicht nachdem das Programm ausgeführt wurde und Sie den Vorgang gerade beenden. – Will

1

Wo rufst du finish() an?

Sie sollten Ihre Ressourcen in onPause und nicht auf onStop freigeben. Es gibt keine Garantie, dass onStop immer aufgerufen wird, bevor Ihre Aktivität beendet wird. Wenn das System Ressourcen benötigt, kann es die Aktivität beenden, bevor onStop aufgerufen wird.

Versuchen Sie, Debug-Protokolle zu erstellen und den Ausführungspfad zu verfolgen, wenn Sie glauben, dass Ihre Anwendung beendet wird.

3

Es klingt, als ob Sie Ihre Anwendung nie Veröffentlichung auf dem Wakelock Aufruf - es möglich ist, dass es eine Ausnahme früher in onStop oder ist zu werfen? Ich würde eine Protokollierung hinzufügen, bei der Sie die Freigabe aufrufen, um zu bestätigen, dass sie ausgeführt wird.

In jedem Fall werden Sie auf jeden Fall jeweils die acquire und release Methoden in onResume und verschieben möchten. Der Code, den Sie haben, wird den WakeLock erst beim ersten Start Ihrer Anwendung erhalten.

Dank der Hintergrundverarbeitung des Androids hat Ihr Code möglicherweise ein Ungleichgewicht. Wenn der Benutzer die Home-Taste drückt, um die Anwendungen zu wechseln, wird die Sperre aufgehoben. Wenn sie zu Ihrer App zurückkehren, wird onCreate nicht aufgerufen, sodass die Sperre nicht übernommen wird.

Ihre beste Wette ist, das WakeLock in onCreate zu konstruieren (wie Sie haben), die Sperre in onResume zu erwerben und es in onPause (einschließlich des Aufrufs zu isHeld) freizugeben. Dies garantiert, dass die Sperre immer dann aufrechterhalten wird, wenn sich Ihre Anwendung im Vordergrund befindet.

2

Ich hatte Probleme, Daten freizugeben, als ich OpenGL verwendete. Also jetzt, mit android.os.Process.killProcess (android.os.Process.myPid()); es funktioniert genau so, wie ich es will !!

Dank Kunst

3

I mWakelock.setReferenceCounted (false) verwenden, weiß nicht, nach wie vor, was es bedeutet, aber es löst meine "WakeLock unter-locked" -Problem.

Init: OnStart() acquire: onResume() Release: OnStop()

Verwandte Themen