我正在尝试使用camera2 api使用zbar读取二维码。不幸的是,当我在成功扫描二维码后尝试完成活动时,出现以下错误:
Handler (android.os.Handler) {282a7034} sending message to a Handler on a dead thread
java.lang.IllegalStateException: Handler (android.os.Handler) {282a7034} sending message to a Handler on a dead thread
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325)
at android.os.Handler.enqueueMessage(Handler.java:631)
at android.os.Handler.sendMessageAtTime(Handler.java:600)
at android.os.Handler.sendMessageDelayed(Handler.java:570)
at android.os.Handler.post(Handler.java:326)
at android.hardware.camera2.dispatch.HandlerDispatcher.dispatch(HandlerDispatcher.java:61)
at android.hardware.camera2.dispatch.MethodNameInvoker.invoke(MethodNameInvoker.java:88)
at android.hardware.camera2.dispatch.DuckTypingDispatcher.dispatch(DuckTypingDispatcher.java:53)
at android.hardware.camera2.dispatch.ArgumentReplacingDispatcher.dispatch(ArgumentReplacingDispatcher.java:74)
at android.hardware.camera2.dispatch.BroadcastDispatcher.dispatch(BroadcastDispatcher.java:54)
at android.hardware.camera2.dispatch.MethodNameInvoker.invoke(MethodNameInvoker.java:88)
at android.hardware.camera2.impl.CallbackProxies$DeviceCaptureCallbackProxy.onCaptureCompleted(CallbackProxies.java:120)
at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$4.run(CameraDeviceImpl.java:1362)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
下面是相关的代码片段:
private CameraCaptureSession.CaptureCallback mCaptureCallback
= new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
Bitmap barcodeBmp = mTextureView.getBitmap();
if(barcodeBmp == null)
return;
int width = barcodeBmp.getWidth();
int height = barcodeBmp.getHeight();
Image mQRCode = new Image(width, height, "RGB4");
final ImageScanner scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
scanner.setConfig(0, Config.ENABLE, 0); //Disable all the Symbols
scanner.setConfig(Symbol.QRCODE, Config.ENABLE, 1); //Only QRCODE is enable
int[] pixels = new int[(width * height)];
barcodeBmp.getPixels(pixels, 0, width, 0, 0, width, height);
mQRCode.setData(pixels);
int scanResult = scanner.scanImage(mQRCode.convert("Y800"));
Log.i(TAG, "Result = " + scanResult);
if(scanResult != 0) {
Log.i(TAG, "Getting results");
SymbolSet syms = scanner.getResults();
Log.i(TAG, "Have results");
for(Symbol sym : syms) {
Intent returnIntent = new Intent();
returnIntent.putExtra("Result", sym.getData());
setResult(RESULT_OK, returnIntent);
closeCamera();
stopBackgroundThread();
mActivity.finish();
}
}
}
};
private void closeCamera() {
try {
mCameraOpenCloseLock.acquire();
if (null != mCaptureSession) {
mCaptureSession.close();
mCaptureSession = null;
}
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
if (null != mImageReader) {
mImageReader.close();
mImageReader = null;
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
} finally {
mCameraOpenCloseLock.release();
}
}
private void stopBackgroundThread() {
if(mBackgroundThread != null) {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join(1);
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
如何停止调用captureCallback并将结果干净地返回到主活动?
最佳答案
您正在呼叫CameraDevice#close()
,但这不会立即关闭摄像机。你应该让线程一直运行直到设备完成。
您的代码可能基于Google’s Camera2 sample app。要整洁地完成所有工作,请停止CameraDevice.StateCallback
中的线程,而不是重写#onClosed(CameraDevice)
方法:
private CameraDevice.StateCallback mStateCallback
= new CameraDevice.StateCallback() {
// ...
@Override
public void onClosed(CameraDevice camera) {
// Keep the thread alive until the camera is closed.
stopBackgroundThread();
}
};
当前的行为可能是一个bug,因为documentation for
CameraDevice#close()
表示:紧接着在这个调用之后,除了最后的
onClosed(CameraDevice)
调用之外,不会再发生来自设备或活动会话的回调,并且任何剩余的提交的捕获请求都将被丢弃,就像abortCaptures()
已经被调用一样,除了不会调用成功或失败的回调。关于android - 停止CaptureCallback请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29402828/