TextureView throwing fatal signal 11 after resuming application
android, textureview
Solution
When the `TextureView` loses visibility (either because the screen is rotated, other `Activity` comes to the front or you press the Home button) it nullifies its `SurfaceTexture.OnFrameAvailableListener` (on GrepCode). It looks like when this happens and at that very moment the `Canvas` instance is executing `drawX()` methods natively on C++ code the app will crash because for some reason the memory containing that canvas is cleared before the method is finished. However, because `Canvas.drawX()` methods make use of Android native C++ code, C++ doesn't throw a `NullPointerException` (How to catch the null pointer exception?) and hence the Java exception handling system is in this case useless.
This issue renders unusable the `TextureView` class as long as you call `drawX()` methods more than a bunch of times or you draw some complex stuff on the `Canvas`.
Pretty much like a bug on threading and/or on the C++ code side. I've opened an issue reporting this: https://code.google.com/p/android/issues/detail?id=85380.
EDIT: I've found a reliable way to avoid calling `drawX()` methods when the `TextureView` isn't visible any more and hence the app starts crashing: interrupt the thread that is drawing on the `Canvas` and check before every call to any `drawX()` method that the thread is interrupted. Prior `onPause()` is called `drawX()` methods won't throw any error.
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();
And then on `onPause()` –just the moment before when calling `Canvas.drawX()` will start to crash the app– interrupt the thread:
@Override
public void onPause() {
super.onPause();
if (mThread != null) {
mThread.interrupt();
mThread = null;
}
}
Add also the same code to `onStop()` and to `onDestroy()`. I've also tried to use the `TextureView.onVisibilityChanged()` method by overriding it to interrupt the thread. But this method is invoked almost 500 ms after `onPause()` is called when it's too late and `drawX()` calls start to crash the app.
Problem
I have a TextureView based on Romain Guy's example which can be found here. On Android 4.3 and 4.4, after a few rounds of pausing and resuming the application, the application crashes and the only trace of an error is a fatal signal 11 in LogCat. I created a test application which uses Romain Guy's exact code to see if it was something I had done in my code and Romain's code crashes with the fatal signal 11, too. I have determined that if I run the code with a Handler instead of a Thread, it does not seem to crash the application. The Handler should be running on the main UI thread (or at least I believe it is), which is perhaps suggesting it is a threading issue. I have also determined that the crash occurs during a call to canvas.drawX (drawColor, drawBitmap, drawRect, etc...). Locking and unlocking the canvas does not seem to be an issue. I suspect that the thread is being cancelled while some other code is still using the canvas, but I am having a very difficult time tracking the issue due to a lack of any real exceptions being thrown and the crash being fairly inconsistent. Any insights would be greatly appreciated.