问题描述
android P 相机添加联系人拍照报错–编辑联系人时后摄拍照,4次点击重拍,相机闪退,再4次重拍相机停止运行 100%
LOG 分析
通过main log 查找crash 发现
--------- beginning of crash
01-13 17:48:32.569 5508 6503 E AndroidRuntime: FATAL EXCEPTION: PostProcessorThread
01-13 17:48:32.569 5508 6503 E AndroidRuntime: Process: org.codeaurora.snapcam, PID: 5508
01-13 17:48:32.569 5508 6503 E AndroidRuntime: java.lang.IllegalStateException: maxImages (3) has already been acquired, call #close before acquiring more.
01-13 17:48:32.569 5508 6503 E AndroidRuntime: at android.media.ImageReader.acquireNextImage(ImageReader.java:502)
01-13 17:48:32.569 5508 6503 E AndroidRuntime: at com.android.camera.imageprocessor.PostProcessor$8.onImageAvailable(PostProcessor.java:1160)
01-13 17:48:32.569 5508 6503 E AndroidRuntime: at android.media.ImageReader$ListenerHandler.handleMessage(ImageReader.java:800)
01-13 17:48:32.569 5508 6503 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
01-13 17:48:32.569 5508 6503 E AndroidRuntime: at android.os.Looper.loop(Looper.java:193)
01-13 17:48:32.569 5508 6503 E AndroidRuntime: at android.os.HandlerThread.run(HandlerThread.java:65)
从上面log可以得到是ImagerReader.java 发生异常
public Image acquireNextImage() {
// Initialize with reader format, but can be overwritten by native if the image
// format is different from the reader format.
SurfaceImage si = new SurfaceImage(mFormat);
int status = acquireNextSurfaceImage(si);
switch (status) {
case ACQUIRE_SUCCESS:
return si;
case ACQUIRE_NO_BUFS:
return null;
case ACQUIRE_MAX_IMAGES:
throw new IllegalStateException(
String.format(
"maxImages (%d) has already been acquired, " +
"call #close before acquiring more.", mMaxImages));
default:
throw new AssertionError("Unknown nativeImageSetup return code " + status);
}
}
通过分析camera源码发现:
ImageReader.OnImageAvailableListener processedImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
final Image image = reader.acquireNextImage();
if(DEBUG_ZSL) Log.d(TAG, "ZSL image Reprocess is done "+image.getTimestamp());
mSavingHander.post(new Runnable() {
public void run() {
long captureStartTime = System.currentTimeMillis();
mNamedImages.nameNewImage(captureStartTime);
PhotoModule.NamedImages.NamedEntity name = mNamedImages.getNextNameEntity();
String title = (name == null) ? null : name.title;
long date = (name == null) ? -1 : name.date;
image.getPlanes()[0].getBuffer().rewind();
int size = image.getPlanes()[0].getBuffer().remaining();
byte[] bytes = new byte[size];
image.getPlanes()[0].getBuffer().get(bytes, 0, size);
ExifInterface exif = Exif.getExif(bytes);
int orientation = Exif.getOrientation(exif);
if (mController.getCurrentIntentMode() != CaptureModule.INTENT_MODE_NORMAL) {
mController.setJpegImageData(bytes);
if (mController.isQuickCapture()) {
mController.onCaptureDone();
} else {
mController.showCapturedReview(bytes, orientation);
}
//此处需要image.close();
} else {
mActivity.getMediaSaveService().addImage(
bytes, title, date, null, image.getCropRect().width(), image.getCropRect().height(),
orientation, null, mController.getMediaSavedListener(), mActivity.getContentResolver(), "jpeg");
mController.updateThumbnailJpegData(bytes);
image.close();
Log.d(TAG,"wangjicong image close 11111");
}
}
});
}
};
是由于缺少image.close() 造成的。
结论
ImageReader 用完后要记得释放所有资源 close();