5

我有一个基于 Romain Guy 示例的 TextureView,可以在此处找到。在 Android 4.3 和 4.4 上,经过几轮暂停和恢复应用程序后,应用程序崩溃了,唯一的错误痕迹是 LogCat 中的致命信号 11。我创建了一个测试应用程序,它使用 Romain Guy 的确切代码来查看它是否是我在代码中所做的事情,并且 Romain 的代码也因致命信号 11 而崩溃。

我已经确定,如果我使用 Handler 而不是 Thread 运行代码,它似乎不会使应用程序崩溃。处理程序应该在主 UI 线程上运行(或者至少我相信它是),这可能表明它是一个线程问题。

我还确定崩溃发生在调用 canvas.drawX(drawColor、drawBitmap、drawRect 等)期间。锁定和解锁画布似乎不是问题。我怀疑线程正在被取消,而其他一些代码仍在使用画布,但是由于没有抛出任何真正的异常并且崩溃相当不一致,因此我很难跟踪问题。

任何见解将不胜感激。

4

3 回答 3

2

TextureView失去可见性时(或者因为屏幕旋转,其他Activity人来到前面或者你按下 Home 按钮)它会取消它SurfaceTexture.OnFrameAvailableListener(在GrepCode上)。看起来当这种情况发生并且在那个时刻Canvas实例drawX()在 C++ 代码上本地执行方法时,应用程序将崩溃,因为由于某种原因,包含该画布的内存在方法完成之前被清除。但是,由于Canvas.drawX()方法使用 Android 原生 C++ 代码,C++ 不会抛出NullPointerException如何捕获空指针异常?),因此 Java 异常处理系统在这种情况下是无用的。

TextureView只要您多次调用方法drawX()或在Canvas.

很像线程和/或 C++ 代码方面的错误。我已经打开了一个报告此问题的问题:https ://code.google.com/p/android/issues/detail?id=85380 。

编辑:我找到了一种可靠的方法来避免在不再可见drawX()时调用方法,因此应用程序开始崩溃:中断正在绘制的线程并在每次调用线程被中断的任何方法之前检查。Prior被调用的方法不会抛出任何错误。TextureViewCanvasdrawX()onPause()drawX()

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();

然后——就在调用将开始使应用程序崩溃的onPause()前一刻——中断线程:Canvas.drawX()

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

也将相同的代码添加到onStop()onDestroy()。我还尝试TextureView.onVisibilityChanged()通过覆盖它来中断线程来使用该方法。但是这个方法在调用后近 500 毫秒onPause()被调用,当它太晚并且drawX()调用开始使应用程序崩溃时。

于 2014-12-19T17:29:07.597 回答
0

我有类似的问题,结果发现这是我的代码中的一个微不足道的 NullPointerException,它以某种方式导致了整个过程的分段错误(信号 11)。显然SurfaceTextureListener.onSurfaceTextureAvailable()回调中的异常没有得到正确处理。这可能是一些 JNI 问题。

作为一种肮脏的解决方法,您可以捕获所有SurfaceTextureListener异常

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

我决定不报告 Android 错误,因为我无法在 4.4.2 上重现它,所以它可能已经修复。

于 2014-04-04T11:05:29.063 回答
-1

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

于 2014-07-10T10:53:04.977 回答