Хорошо, так что после нескольких недель охоты на эту ошибку я наконец узнал, что случилось. Я разместил решение здесь, на тот случай, если кто-то еще споткнется об этой проблеме.
Иногда функция publi c void onImageAvailable (читатель ImageReader) {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);
}
}