TextureViewを継承したViewをFragment内に配置し、何度か表示すると Fatal signal 11 (SIGSEGV)が出る
下記のような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:
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) {
}
}
}
}
Fragmentへの配置
textureanim = new TextureAnimation(context);
frameLayout.addView(textureanim, new ViewGroup.LayoutParams(MP, MP));
Logcat
Fatal signal 11 (SIGSEGV) at 0x93f3a5f4 (code=1), thread 5581 (Thread-644)