У меня есть следующий код, с которым я пытаюсь сделать снимок и сохранить часть информации о фотографии в базе данных. Часть базы данных была тщательно протестирована и отлично работает во всех других обстоятельствах. К сожалению, если я раскомментирую приведенный ниже код, мой код не работает. По какой-то причине, если существует код, следующий за this.camera.takePicture()
метод takePicture()
не будет вызывать метод onPictureTaken
вообще (первое, что он должен сделать, это распечатать строку текста, но это даже не делает этого). Если после него нет кода, он работает нормально.
Перед установкой защелки я получил бы ошибку, потому что ph.getPhoto()
возвращал значение null
(.photo
член .photo
еще не была установлена onPictureTaken()
, потому что она еще не была вызвана). После установки защелки он будет ждать до таймаута (или навсегда, если не указано значение тайм-аута).
Может кто-нибудь, пожалуйста, скажите мне, что мне не хватает?
public void takePicture(View view) throws Exception {
CountDownLatch latch = new CountDownLatch(1);
System.out.println("Taking Photo!");
PhotoHandler photoHandler = new PhotoHandler(getApplicationContext(),latch);
this.camera.takePicture(null, null, photoHandler);
/* PhotoHandler has an overridden "onPictureTaken()" method which releases the latch as its final
* action; however, its first instruction is to print a confirmation that it has been accessed.
* Unfortunately, for some reason, onPictureTaken() is not called if the following code is
* uncommented; it deadlocks for the five seconds before timing out. However, with out the following,
* the camera.takePicture method invokes onPictureTaken() and it works just fine. */
// latch.await(5,TimeUnit.SECONDS);
// DatabaseHandler db = new DatabaseHandler(this);
// Photo p = photoHandler.getPhoto();
// db.addPhoto(p);
// List<Photo> photos = new ArrayList<Photo>();
// photos.add(p);
// this.addPhotosToMap(photos);
}
onPictureTaken()
is (afaik), выполняемый по потоку основного/пользовательского интерфейса. Если вы также takePicture
метод takePicture, это должно произойти просто потому, что поток не может дождаться самого себя.
Кроме того, вы не должны блокировать mainthread, или ваша активность будет ANR.
Если вы переместите прокомментированный код (минус эта защелка) на onPictureTaken()
все будет хорошо. Те, onSomethingHappened
совершил то же onSomethingHappened
обратные вызовы именно для этой задачи
Поместите всю свою пост-обработку (то есть код, который вы закомментировали) в соответствующий обратный вызов, а не после takePicture. И добавьте медленные действия, такие как доступ к файловой системе в фоновый поток (например, AsyncTask).
onPictureTaken()
, но я переместил его, чтобы посмотреть, не является ли это причиной проблемы. Я могу положить его обратно, но это не решит мою проблему. В любом случае, я могу выполнить все элементы файловой системы мгновенно - это не проблема (спасибо за совет) - с закомментированной последней частью кода. Почему код после camera.takePicture()
влияет на то, вызывает ли он onPictureTaken()
?
takePicture
является частью основного действия и выполняется кнопкой. Я понятия не имею, как проверить, какой поток это часть. Я согласился бы, что это должно произойти; однако, как я уже сказал, этого не произойдет, если последняя часть кода не будет удалена. Он даже не выполняет первую инструкцию, которая является простым sysout. Во-вторых, я знаю, что не должен блокировать поток, но метод getPhoto () не должен выполняться перед методом, который устанавливает фотографию. Я могу переместить это позже или снять защелку, но это не решает мою проблему прямо сейчас.onPictureTaken()
, но он тоже не понравился, поэтому я переместил его в попытке выяснить, в чем дело. Я могу переместить это назад, но это не решает проблему. В любом случае, кроме db, оставшаяся часть этого закомментированного кода отвечает за заполнение просмотра карты маркером новой фотографии. Разве это не должно оставаться частью интерфейса? И если нет, как я должен сказать onPictureTaken манипулировать пользовательским интерфейсом?