我在使用AndroidStudio自带的示例程序时遇到了一个问题。我只在S8上试过,所以我不确定这是这个特定设备的问题还是通用的。
如果我尝试在一次拍摄中拍摄多张照片,通过将mPendingUserCaptures设置为像4这样的数字,特别是如果我手动将曝光时间设置为一个低值(通常低于30ms左右),我总是得到4张JPG图像,但有时我只得到3个原始文件(最后一个丢失).问题是在ImageSaver类中,它并不总是为RAW文件调用,但总是为JPG调用。
我想知道,有没有人经历过这样的事情,当一个RAW图像有时不会到达?
好了,所以经过几个星期的狩猎这个错误的和关闭,我终于找到了发生了什么事.我在这里发布的解决方案,只是为了防止别人绊倒周围这个问题。
有时函数 public void onImageAvailable(ImageReader reader) { dequeueAndSaveImage(mRawResultQueue, mRawImageReader); }会被连续调用两次。
代码是这样的。
Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry = pendingQueue.firstEntry();
ImageSaver.ImageSaverBuilder builder = entry.getValue();
这就产生了一个巨大的问题,因为有时两个图像会被添加到同一个TreeMap条目中,所以如果我们有4个条目,最后一个条目将永远不会得到它的图像。
The fixed code (I left my extra logs there) looks like this:
private void dequeueAndSaveImage(TreeMap<Integer, ImageSaver.ImageSaverBuilder> pendingQueue, RefCountedAutoCloseable<ImageReader> reader) {
synchronized (mCameraStateLock) {
ImageSaver.ImageSaverBuilder builder=null;
Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry;
int key=4;//shut up, stupid java shit
for (Map.Entry<Integer, ImageSaver.ImageSaverBuilder> ent : pendingQueue.entrySet()) {
builder = ent.getValue();
if(builder.mImage==null) {
key = ent.getKey();
break;
}
}
//Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry = pendingQueue.firstEntry();
//ImageSaver.ImageSaverBuilder builder = entry.getValue();
Log.w(TAG, "StartingdequeueAndSaveImage, builder: " + builder);
if(builder.mImage!=null)
{
Log.w(TAG, "!!!!!!!!!!!!!!!!!!!!Builder: " + builder + " already has an image!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
// Increment reference count to prevent ImageReader from being closed while we
// are saving its Images in a background thread (otherwise their resources may
// be freed while we are writing to a file).
if (reader == null || reader.getAndRetain() == null) {
Log.e(TAG, "Paused the activity before we could save the image," + " ImageReader already closed.");
pendingQueue.remove(key);
return;
}
Image image;
try {
image = reader.get().acquireNextImage();
} catch (IllegalStateException e) {
Log.e(TAG, "Too many images queued for saving, dropping image for request: " + key);
pendingQueue.remove(key);
return;
}
builder.setRefCountedReader(reader).setImage(image);
if(image==null)Log.e(TAG, "Cacatul de imagine e null...... Sa ma fut in mortii lor.");
handleCompletionLocked(key, builder, pendingQueue);
Log.e(TAG, "Call handled completed in deque" + pendingQueue);
}
}