TextureView 不断收到 SIGSEGV 11
TextureView keeps getting SIGSEGV 11
我找到了 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
我会在 stopRendering 函数中换行,来自:
public void stopRendering() {
interrupt();
mRunning = false;
}
至:
public void stopRendering() {
mRunning = false;
interrupt();
}
原因是有可能interrupt()
会中断你线程中的sleep(),然后render线程会继续执行,会发现mRunning仍然为真。我不确定这是否是导致您崩溃的问题。
[编辑]
使代码更可靠的提示:
- 正如 fadden 在评论中所写,在 stopRendering() 中等待渲染线程结束是个好主意。
- 您可以在锁定它之前检查
mSimulationAnimationView.getSurface().isValid()
,如果它为 false,则 continue
循环您的渲染线程。
- 调用
lockCanvas(null)
后,请在使用前检查结果是否为非空。在 docs 它说:
If null is not returned, this function internally holds a lock until the corresponding unlockCanvasAndPost(Canvas) call, preventing SurfaceView from creating, destroying, or modifying the surface while it is being drawn.
所以一旦你有了锁,你应该是安全的
在 onPause()
returns 之前停止渲染很重要,因为框架会开始拆解。一个简单而有效的方法是让渲染器线程停止,并等待它用 Thread#join()
.
停止。
"sleep for a while" 方法的替代方法是使用 Choreographer (API 16+), which invokes a callback on VSYNC. You may still want to do the rendering in a separate thread for better performance on multi-core devices. The "record GL app" activity in Grafika 使用 Choreographer 向使用标准 Android Looper/Handler 机制的渲染器线程发送信号。它始终以 60fps 的速度呈现,并展示了一种在系统变慢时丢帧的粗略机制。
(注意 Grafika 示例使用 SurfaceView,而不是 TextureView,规则略有不同——SurfaceView 表面的生命周期与 onPause()
无关,因此线程停止和连接实际上发生在 surfaceDestroyed()
回调。)
另请参阅图形架构文档中的“game loops”部分。
我找到了 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
我会在 stopRendering 函数中换行,来自:
public void stopRendering() {
interrupt();
mRunning = false;
}
至:
public void stopRendering() {
mRunning = false;
interrupt();
}
原因是有可能interrupt()
会中断你线程中的sleep(),然后render线程会继续执行,会发现mRunning仍然为真。我不确定这是否是导致您崩溃的问题。
[编辑]
使代码更可靠的提示:
- 正如 fadden 在评论中所写,在 stopRendering() 中等待渲染线程结束是个好主意。
- 您可以在锁定它之前检查
mSimulationAnimationView.getSurface().isValid()
,如果它为 false,则continue
循环您的渲染线程。 - 调用
lockCanvas(null)
后,请在使用前检查结果是否为非空。在 docs 它说:
If null is not returned, this function internally holds a lock until the corresponding unlockCanvasAndPost(Canvas) call, preventing SurfaceView from creating, destroying, or modifying the surface while it is being drawn.
所以一旦你有了锁,你应该是安全的
在 onPause()
returns 之前停止渲染很重要,因为框架会开始拆解。一个简单而有效的方法是让渲染器线程停止,并等待它用 Thread#join()
.
"sleep for a while" 方法的替代方法是使用 Choreographer (API 16+), which invokes a callback on VSYNC. You may still want to do the rendering in a separate thread for better performance on multi-core devices. The "record GL app" activity in Grafika 使用 Choreographer 向使用标准 Android Looper/Handler 机制的渲染器线程发送信号。它始终以 60fps 的速度呈现,并展示了一种在系统变慢时丢帧的粗略机制。
(注意 Grafika 示例使用 SurfaceView,而不是 TextureView,规则略有不同——SurfaceView 表面的生命周期与 onPause()
无关,因此线程停止和连接实际上发生在 surfaceDestroyed()
回调。)
另请参阅图形架构文档中的“game loops”部分。