TextureView不断获得SIGSEGV 11

时间:2015-06-17 15:25:40

标签: java android sigsegv textureview

我找到this Solution,但不幸的是,它对我不起作用。当我只显示一个小的移动矩形,所以没有动画,它工作正常,但我想显示一些我用.png加载的动画帧,每当我最小化我的应用程序或按后退按钮,我立即得到SIGSEV错误。

对于我绘制了一个有很多点的图形的一个屏幕,我找到了一个解决方案,我在完成绘制线条之后就停止了线程,但是因为我需要显示一个动态动画我不能做它在这个特定的片段中。

我的渲染线程代码如下所示:

private class RenderThread extends Thread {
    private volatile boolean mRunning = true;
    int framecount = 1;

    @Override
    public void run() {


        while (mRunning && !Thread.interrupted()) {

            final Canvas canvas = mSimulationAnimationView.lockCanvas(null);

            try {
                canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                drawCar(canvas);
            } finally {
                mSimulationAnimationView.unlockCanvasAndPost(canvas);
            }

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // Sleep if the Thread is interrupted
            }
        }
    }

    public void stopRendering() {
        interrupt();
        mRunning = false;
    }


    private void drawCar(Canvas canvas){

        if(framecount==1){
            canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.piston_frame_one), 10, 10, null);
            framecount++;
        }
        else{
            canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.piston_frame_two), 10, 10, null);
            framecount--;

        }



    }

}//RenderThread

这显然是基于Romain Guy的例子,可以找到here

非常感谢帮助!

编辑:崩溃转储就是这个:

********** Crash dump: **********
Build fingerprint: 'google/hammerhead/hammerhead:5.1.1/LMY48B/1863243:user/release-keys'
pid: 16130, tid: 16343, name: Thread-19966  >>> package.package.package <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x9ee3ad10
Stack frame #00 pc 001b474a  /system/lib/libskia.so (S32A_Opaque_BlitRow32_neon_src_alpha(unsigned int*, unsigned int const*, int, unsigned int)+109)
Stack frame #01 pc 001072fb  /system/lib/libskia.so
Stack frame #02 pc 00103793  /system/lib/libskia.so
Stack frame #03 pc 0010385f  /system/lib/libskia.so (SkScan::FillIRect(SkIRect const&, SkRegion const*, SkBlitter*)+198)
Stack frame #04 pc 0010395f  /system/lib/libskia.so (SkScan::FillIRect(SkIRect const&, SkRasterClip const&, SkBlitter*)+36)
Stack frame #05 pc 000e0e27  /system/lib/libskia.so (SkDraw::drawBitmap(SkBitmap const&, SkMatrix const&, SkPaint const&) const+464)
Stack frame #06 pc 000d90c9  /system/lib/libskia.so
Stack frame #07 pc 000d91b1  /system/lib/libskia.so (SkCanvas::drawBitmap(SkBitmap const&, float, float, SkPaint const*)+116)
Stack frame #08 pc 000947d1  /system/lib/libandroid_runtime.so (android::SkiaCanvas::drawBitmap(SkBitmap const&, float, float, SkPaint const*)+12)
Stack frame #09 pc 0008a7b7  /system/lib/libandroid_runtime.so
Stack frame #10 pc 007eff33  /data/dalvik-cache/arm/system@framework@boot.oat

2 个答案:

答案 0 :(得分:2)

我会在stopRendering函数中切换行:

public void stopRendering() {
    interrupt();
    mRunning = false;
}

为:

public void stopRendering() {
    mRunning = false;
    interrupt();
}

原因是interrupt()可能会破坏你的线程中的sleep(),然后渲染线程将继续执行并且会发现mRunning仍然是真的。我不确定这是否是导致您崩溃的问题。

[编辑]

提示使代码更可靠:

  1. 正如fadden在评论中写的那样,最好在stopRendering()中等待渲染线程结束。
  2. 您可以在锁定之前检查mSimulationAnimationView.getSurface().isValid(),如果它为false,则continue循环渲染线程。
  3. 调用lockCanvas(null)之后,在使用之前检查结果是否为非null。在docs中说:
  4.   

    如果未返回null,则此函数在内部保持锁定,直到相应的unlockCanvasAndPost(Canvas)调用,从而阻止SurfaceView在绘制时创建,销毁或修改曲面。

    所以一旦你有锁,你应该是安全的

答案 1 :(得分:1)

onPause()返回之前停止渲染非常重要,因为框架将开始撕毁。一种简单有效的方法是让渲染器线程停止,并等待它Thread#join()

“暂时休眠”方法的替代方法是使用Choreographer(API 16+),它在VSYNC上调用回调。您可能仍希望在单独的线程中进行渲染,以便在多核设备上获得更好的性能。 record GL app中的“Grafika”活动使用Choreographer来表示使用标准Android Looper / Handler机制的渲染器线程。它始终以60fps呈现,并演示了在系统减速时丢帧的粗略机制。

(注意Grafika示例使用的是SurfaceView,而不是TextureView,规则略有不同 - SurfaceView Surface的生命周期与onPause()无关,因此线程停止和连接实际发生在{{1回调。)

另请参阅图形架构文档中的“game loops”部分。