2013-12-20 14 views
5

Ich habe eine TextureView basierend auf Romain Guy Beispiel, das here gefunden werden kann. Bei Android 4.3 und 4.4 stürzt die Anwendung nach einigen Pausen und dem Fortsetzen der Anwendung ab, und die einzige Spur eines Fehlers ist ein fatales Signal 11 in LogCat. Ich habe eine Testanwendung erstellt, die den genauen Code von Romain Guy verwendet, um zu sehen, ob es etwas war, was ich in meinem Code gemacht habe, und auch der Code von Romain stürzt mit dem fatalen Signal 11 ab.TextureView wirft fatales Signal 11 nach dem Fortsetzen der Anwendung

Ich habe festgestellt, dass, wenn ich den Code mit einem Handler anstelle eines Threads ausführen, scheint es nicht zum Absturz der Anwendung. Der Handler sollte auf dem Hauptthread der Benutzeroberfläche ausgeführt werden (zumindest glaube ich es), was vielleicht darauf hindeutet, dass es sich um ein Threading-Problem handelt.

Ich habe auch festgestellt, dass der Absturz während eines Aufrufs von canvas.drawX (DrawColor, DrawBitmap, DrawRect, etc ...) auftritt. Das Sperren und Entsperren der Arbeitsfläche scheint kein Problem zu sein. Ich vermute, dass der Thread abgebrochen wird, während anderer Code immer noch den Canvas verwendet, aber ich habe eine sehr schwierige Zeit, das Problem zu verfolgen, da keine echten Ausnahmen ausgelöst werden und der Absturz ziemlich inkonsistent ist.

Alle Einsichten würden sehr geschätzt werden.

Antwort

2

Wenn die TextureView Sichtbarkeit verliert (entweder weil der Bildschirm gedreht wird, andere Activity nach vorne kommt, oder Sie drücken Sie die Taste Home) es seine SurfaceTexture.OnFrameAvailableListener (auf GrepCode) zunichte macht. Es sieht aus wie wenn dies geschieht und in diesem Moment die Canvas Instanz drawX() Methoden nativ in C++ - Code die App wird abstürzen, weil aus irgendeinem Grund der Speicher, der diese Leinwand enthält, wird gelöscht, bevor die Methode abgeschlossen ist. Da Canvas.drawX() Methoden jedoch Android nativen C++ - Code verwenden, wirft C++ keine NullPointerException (How to catch the null pointer exception?) und daher ist das Java-Ausnahmebehandlungssystem in diesem Fall nutzlos.

Dieses Problem macht die TextureView Klasse unbrauchbar, solange Sie drawX() Methoden mehr als ein paar Mal aufrufen, oder Sie zeichnen einige komplexe Sachen auf der Canvas.

So ziemlich wie ein Fehler auf Threading und/oder auf der C++ - Code-Seite. Ich habe ein Problem gemeldet, das dies meldet: https://code.google.com/p/android/issues/detail?id=85380.

EDIT: Ich habe eine zuverlässige Art und Weise zu vermeiden Aufruf drawX() Methoden gefunden, wenn die TextureView nicht sichtbar ist mehr und damit die App startet Absturz: unterbricht den Faden, der vor jedem Anruf auf den Canvas und prüfen Sie zeichnen zu irgendeiner drawX() Methode, die der Thread unterbrochen wird.Prior onPause() heißt drawX() Methoden werden keinen Fehler werfen.

mThread = new Thread() { 
    @Override 
    public void run() { 
     Canvas canvas = mTV.lockCanvas(); 

     /** Draw your stuff on the canvas but check before every 
      single drawX() call whether mThread has been interrupted **/ 
     Paint p = new Paint(); 
     p.setColor(Color.RED); 
     for (int n=0; n<5000; ++n) { 
      if (mThread.isInterrupted()) 
       break; 
      canvas.drawCircle(0, 0, 300, p); 
     } 
     /** **/ 

     mTV.unlockCanvasAndPost(canvas); 
    }; 
mThread.start(); 

Und dann auf onPause() -Just Moment vor, wenn Canvas.drawX() Aufruf startet die zum Absturz app- den Thread unterbrechen:

@Override 
public void onPause() { 
    super.onPause(); 
    if (mThread != null) { 
     mThread.interrupt(); 
     mThread = null; 
    } 
} 

auch noch der gleiche Code zu onStop() und onDestroy(). Ich habe auch versucht, die TextureView.onVisibilityChanged() Methode zu verwenden, indem ich es überschreibe, um den Faden zu unterbrechen. Aber diese Methode wird fast 500 ms aufgerufen, nachdem onPause() aufgerufen wird, wenn es zu spät ist und drawX() Anrufe beginnen, die App zum Absturz zu bringen.

+0

Stoppen und Verhindern der Ziehaufrufe bei onPause tatsächlich für mich gearbeitet! eine gute temporäre Lösung für diesen seltsamen Bug. Hoffentlich werden sie es bald beheben. – doomsdaymachine

+0

Kannst du nicht 'Thread.join()' den Renderer-Thread in 'onPause()'? Das sollte sicherstellen, dass es nicht mehr ausgeführt wird, bevor TextureView mit der Bereinigung beginnt. 'interrupt()' ist nicht synchron; es setzt nur eine Flagge und kickt den anderen Thread aus 'wait()'. Wenn der Renderer-Thread weiterhin ausgeführt wird, nachdem 'onPause()' zurückgegeben wurde, ist das ein App-Fehler, kein Framework-Problem. – fadden

0

Ich hatte ähnliches Problem und es stellte sich heraus, es war eine triviale NullPointerException in meinem Code, die irgendwie Segmentation Fehler (Signal 11) des gesamten Prozesses verursacht. Anscheinend werden Ausnahmen innerhalb von SurfaceTextureListener.onSurfaceTextureAvailable() Callbacks nicht korrekt behandelt. Es ist wahrscheinlich ein JNI-Problem.

Als schmutzig Abhilfe Sie alle Ausnahmen von SurfaceTextureListener mit fangen

try { 
} catch (Throwable t) { 
    //do some tear down - better than signal 11 
} 

ich entschieden, den Android Fehler zu melden, da ich es nicht wiedergeben kann auf 4.4.2 so wahrscheinlich es behoben wurde.

+1

Ich kam heute zu diesem Thema zurück und ich kann bestätigen, dass das Problem auf 4.4.4 noch existiert, obwohl es schwieriger zu reproduzieren scheint. Ich habe bei jedem Methodenaufruf, den ich mache, try/catch-Anweisungen gesetzt, aber ich kann den Fehler immer noch nicht abfangen. Mein Fehler ist SIGSEGV = Segmentierungsfehler in nativem Code, was wahrscheinlich erklärt, warum keine Ausnahmen ausgelöst werden. – Kaleb

-1

if (Build.VERSION.SDK_INT> Build.VERSION_CODES.HONEYCOMB) webview.setLayerType (View.LAYER_TYPE_SOFTWARE, null);

+0

Dies hat das Problem leider nicht behoben. – Kaleb

+0

Diese Antwort wäre viel nützlicher mit einer Erklärung dessen, was es zu erreichen versucht und warum es geholfen hat. Meine beste Vermutung ist, dass dies die Chancen auf einen Rennzustand ändern würde, der das Problem nicht wirklich löst. – fadden

+0

dies ist völlig nicht mit Problem –