在某些设备上 Surface.nativeLockCanvas 出现 ANR
ANR on Surface.nativeLockCanvas on some devices
我需要绘制来自加速度计的事件 SurfaceView
。
我创建回调以检查表面是否准备就绪。
overlaySurfaceView = (SurfaceView) findViewById(R.id.overlay_surface);
overlaySurfaceView.setZOrderMediaOverlay(true);
overlayHolder = overlaySurfaceView.getHolder();
overlayHolder.setFormat(PixelFormat.TRANSPARENT);
overlayHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
overlayReady = true;
Log.d(TAG, "SET overlayReady = true");
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
overlayReady = false;
Log.d(TAG, "SET overlayReady = false");
}
});
在传感器侦听器中我锁定 canvas 并绘制一些东西
private final SensorEventListener orientationListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
Log.d(TAG, "onSensorChanged: overlayReady = " + overlayReady);
if (!overlayReady)
return;
if (overlayHolder == null || overlayHolder.isCreating() || !overlayHolder.getSurface().isValid()) {
return;
}
Canvas canvas = overlayHolder.lockCanvas();
if (canvas == null) {
return;
}
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Some drawing
overlayHolder.unlockCanvasAndPost(canvas);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
但是从一个 Transformer Pad (TF103CG) (K018)
的客户端,我收到一个描述为 正在等待的 ANR,因为被触摸的 window 还没有完成处理之前传递给它的输入事件。
----- pid 10710 at 2016-03-02 17:25:43 -----
Cmd line: com.####.#####
JNI: CheckJNI is off; workarounds are off; pins=0; globals=295
DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)
"main" prio=5 tid=1 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x430f7340 self=0x430e4620
| sysTid=10710 nice=0 sched=0/0 cgrp=apps handle=1073954880
| state=S schedstat=( 11049431919 2136334229 17921 ) utm=902 stm=202 core=1
(native backtrace unavailable)
at android.view.Surface.nativeLockCanvas(Native Method)
at android.view.Surface.lockCanvas(Surface.java:243)
at android.view.SurfaceView.internalLockCanvas(SurfaceView.java:822)
at android.view.SurfaceView.lockCanvas(SurfaceView.java:790)
at com.####.#####.CustomCameraActivity.onSensorChanged(CustomCameraActivity.java:342)
at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:418)
ANR 日志全文here.
哪里会出问题?
作为解决方案,我创建了另一个线程并将代码从 onSensorChanged
移至该线程。
在一个线程中,我使用 canvas 并休眠 100 毫秒。 onSensorChanged
现在我只保存传感器值。
我需要绘制来自加速度计的事件 SurfaceView
。
我创建回调以检查表面是否准备就绪。
overlaySurfaceView = (SurfaceView) findViewById(R.id.overlay_surface);
overlaySurfaceView.setZOrderMediaOverlay(true);
overlayHolder = overlaySurfaceView.getHolder();
overlayHolder.setFormat(PixelFormat.TRANSPARENT);
overlayHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
overlayReady = true;
Log.d(TAG, "SET overlayReady = true");
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
overlayReady = false;
Log.d(TAG, "SET overlayReady = false");
}
});
在传感器侦听器中我锁定 canvas 并绘制一些东西
private final SensorEventListener orientationListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
Log.d(TAG, "onSensorChanged: overlayReady = " + overlayReady);
if (!overlayReady)
return;
if (overlayHolder == null || overlayHolder.isCreating() || !overlayHolder.getSurface().isValid()) {
return;
}
Canvas canvas = overlayHolder.lockCanvas();
if (canvas == null) {
return;
}
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Some drawing
overlayHolder.unlockCanvasAndPost(canvas);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
但是从一个 Transformer Pad (TF103CG) (K018)
的客户端,我收到一个描述为 正在等待的 ANR,因为被触摸的 window 还没有完成处理之前传递给它的输入事件。
----- pid 10710 at 2016-03-02 17:25:43 -----
Cmd line: com.####.#####
JNI: CheckJNI is off; workarounds are off; pins=0; globals=295
DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)
"main" prio=5 tid=1 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x430f7340 self=0x430e4620
| sysTid=10710 nice=0 sched=0/0 cgrp=apps handle=1073954880
| state=S schedstat=( 11049431919 2136334229 17921 ) utm=902 stm=202 core=1
(native backtrace unavailable)
at android.view.Surface.nativeLockCanvas(Native Method)
at android.view.Surface.lockCanvas(Surface.java:243)
at android.view.SurfaceView.internalLockCanvas(SurfaceView.java:822)
at android.view.SurfaceView.lockCanvas(SurfaceView.java:790)
at com.####.#####.CustomCameraActivity.onSensorChanged(CustomCameraActivity.java:342)
at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:418)
ANR 日志全文here.
哪里会出问题?
作为解决方案,我创建了另一个线程并将代码从 onSensorChanged
移至该线程。
在一个线程中,我使用 canvas 并休眠 100 毫秒。 onSensorChanged
现在我只保存传感器值。