4890


下記のようなTextureViewを継承したViewを作成してFragment内に配置し、Fragmentの表示・リプレースを何度か繰り返すと Fatal
signal 11 (SIGSEGV) が出て終了します。

試したことは

  * 表示・リプレースを繰り返した時、数回でFatal signal 11 (SIGSEGV)となる場合もあれば、ずっと繰り返してやっと出る場合もある。
  * 表示上の都合でSurfaceViewからTextureViewに変更したのですが、SurfaceViewでは同じようなこと（オーバーライドしたrunメソッド内でCanvasにループして描画する）をしてもFatal signal 11 (SIGSEGV)は出なかった。
  * android:largeHeapの設定をしても現象は変わらず、MemoryMonitorとMemoryAnalyzerで調査を行いましたがメモリリークはないようです。

よろしくお願いします。

* * *

## 追記

エミュレータで試したところ現象を再現できませんでした。

現象が発生する端末  
- Xperia Z3 compact 

発生しない端末

  * エミュレータ Genymotion

* * *

参考にしたサイト  
<http://dev.classmethod.jp/slide/introduction_textureview_20130116/>

* * *

TextureViewを継承したView：

[code]

    public class TextureAnimation extends TextureView  implements TextureView.SurfaceTextureListener,Runnable{
    
    
    static final long FPS = 60;
    static final long FRAME_TIME = 1000 / FPS;
    static final int BALL_R = 40;
    Thread thread;
    
    private float scale;
    
    public TextureAnimation(Context context){
        super(context);
        setSurfaceTextureListener(this);
    }
    
    
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
                                          int height) {
        thread=new Thread(this);
        thread.start();
    }
    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        thread=null;
        return false;
    }
    
    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
                                            int height) {
    }
    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    }
    
    @Override
    public void run() {
        Canvas canvas = null;
    
    
        long loopCount = 0;
        long waitTime = 0;
        long startTime = System.currentTimeMillis();
    
    
        //アニメーション用のループ
        while (thread != null) {
            Paint paint = new Paint();
    
    
            paint.setAntiAlias(true);
    
    
            // Ball
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(Color.BLUE);
    
    
                try {
                    loopCount++;
                    canvas = this.lockCanvas();
    
                    scale = scale + 0.025f;
    
                    //透明色で前回の描画を消す
                    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    
                    //玉の描画
                    canvas.save();
                    canvas.scale(scale, scale,50, 50);
                    canvas.drawCircle(50, 50, BALL_R,paint);
                    canvas.restore();
    
                    this.unlockCanvasAndPost(canvas);
    
    
                    waitTime = (loopCount * FRAME_TIME)
                            - (System.currentTimeMillis() - startTime);
    
                    if (scale > 1) {
                        scale = 0;
                    }
    
    
                    if (waitTime > 0) {
                        Thread.sleep(waitTime);
                    }
                } catch (Exception e) {
                }
    
    
        }
    }
    
[/code]

}

Fragmentへの配置

[code]

    textureanim = new TextureAnimation(context);
            frameLayout.addView(textureanim, new ViewGroup.LayoutParams(MP, MP));
    
[/code]

Logcat

[code]

     Fatal signal 11 (SIGSEGV) at 0x93f3a5f4 (code=1), thread 5581 (Thread-644)
    
[/code]


CC BY-SA 3.0
2015-01-20T01:05:05.133
4869
2015-01-20T05:36:45.190
2015-01-20T02:25:55.843
7256
7256
question
android
TextureViewを継承したViewをFragment内に配置し、何度か表示すると Fatal signal 11 (SIGSEGV)が出る


`run()`メソッド内の描画部分が原因だと思います。

`lockCanvas`〜`unlock`までの間に`Fragment`が廃棄されると`TextureView`のリソース廃棄されている状態でCanvasのメソッドが呼ばれて、描画中に落ちているのではないかと思います。

`lockCanvas`手前〜`unlock`までの間を`synchro(this)`あたりで囲って、`onSurfaceTextureXXXXX()`メソッドの中味も`synchro(this)`あたりで囲ってあげてCanvas描画中にライフサイクルを終わらせないようにしたらどうでしょうか？


CC BY-SA 3.0
2015-01-20T05:33:52.587
4890
2015-01-20T05:36:45.190
2015-01-20T05:36:45.190
845
7583
4869
answer