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.

Original source

Related problems