Android LogCat показывает BufferQueueProcedure

Сначала, пожалуйста, извините мой плохой английский. У меня есть окончательная версия моего приложения (школьная работа) - оно делает фотографии, а затем фотографии сшиваются с использованием кода C++. Я протестировал приложение на своем телефоне Xperia mini API 15, на этом устройстве все в порядке. Но я позаимствовал школьный Nexus 5 API 21 и есть две проблемы.

Первая проблема расстраивает. Сегодня я отлаживал весь день без решения. Я понятия не имею, какая часть кода может вызвать эту ошибку. Всякий раз, когда приложение работает — неважно, делает ли оно фото или сшивает, LogCat показывает тысячи этих ошибок:

Tag: BufferQueueProceducer Text: [unnamed-3046-0] dequeueBuffer: Bufferqueue has been abandoned

Код останавливается после этой ошибки. К сожалению, я могу быть более конкретным, потому что я не знаю. где может быть причина.

Вторая проблема только в процессе сшивания фото, когда вдруг показывает Приложение не отвечает (ANR). Но когда я нажимаю «Подождать», приложение продолжает склеивать фотографии. Результат хороший, но диалог раздражает. Я нашел решение на этой странице - проблема в среде выполнения ART. Я хотел изменить среду выполнения с ART на Dalvik, но в Nexus 5 нет возможности для изменения. Есть ли другой выбор? Ошибка в логкат:

Tag: art  Thread[5,tid=6270, `WaitingInMainSignalCatcherLoop,Thread*=0xf60e40,peer=0x12c00080,"Signal Catcher"]: reacting to signal 3`

Спасибо за каждый совет, ЛС

Я упрощаю код (это основная часть), чтобы вы могли легко анализировать, но если хотите, я могу написать все коды здесь.

// button for stitching photo in folder 'img'
public void onlyStitchButtonClicked(View button)
{
    File root = new File(urlStorage + "img");
    if (!root.exists()){
        toaster("Folder '" + urlStorage + "img' doesnt exist");
    }else{
        // show message on TextView
        tOutput.append("Stitching.\n");
        choosenResultSize = getUsersSize();

        // without delay text dont show in TextView
        new Handler().postDelayed(new Runnable() {
            public void run() {
                Stitching(urlStorage, "img", choosenResultSize);
                tOutput.append("End stitching.\n");
            }
        }, 500);        
    }
    return;
}

// Button for taking photo and stitching them
public void startButtonClicked(View button){
    // Get users settings

    tOutput.setText("App is running. Start taking photo.\n");

    // Wait delay before taking first photo
    new Handler().postDelayed(new Runnable() {
        public void run() {
            StartShot();
        }
    }, DelayBeforeStart*1000);
}

// Take collection of photos
private void StartShot(){
    new CountDownTimer(((1+NumOfPhoto)*DelayBetweenShot)*1000, DelayBetweenShot*1000) {
        private int Photo = 0;

        @Override
        public void onTick(long millisUntilFinished) {
            tOutput.append("Photo num. " + ++Photo );

            try{
                camera.takePicture(null, null, mPicture);
            }
            catch(Exception e){}
        }

        @Override
        public void onFinish() {
            tOutput.append("Stop taking photo. Start stitching");
            // Wait delay before taking first photo
            new Handler().postDelayed(new Runnable() {
                public void run() {
                    Stitching(urlStorage, FolderName, choosenResultSize);

                    tOutput.append("Stitching done.");
                    scrollview.fullScroll(ScrollView.FOCUS_DOWN);
                }
            }, 500);
        }

    }.start();
}

person Lukas    schedule 07.05.2015    source источник


Ответы (1)


Проблема №1:

BufferQueues, которые являются механизмом, лежащим в основе Surfaces, имеют схему производитель-потребитель. Для SurfaceView ваше приложение является производителем, а SurfaceFlinger (композитор системной графики) — потребителем. Для SurfaceTexture обе стороны находятся в вашем приложении. Сообщение «BufferQueue было заброшено» означает, что потребительская сторона ушла, например. вы пытаетесь отправить кадры на поверхность SurfaceView, но SurfaceView больше не существует.

Я предполагаю, что любая поверхность, которую вы используете для вывода камеры, была отброшена, и каждый раз, когда камера пытается отправить изображение для предварительного просмотра, вы получаете сообщение об ошибке.

Проблема №2:

Похоже, вы выполняете кучу работы над основным потоком пользовательского интерфейса. Это заставляет систему считать, что приложение не отвечает, и вы получаете диалоговое окно ANR. Часть обработки ANR включает в себя получение трассировки стека от не отвечающего процесса; поскольку он не может спросить обычными средствами, он отправляет сигнал 3. Сообщение от виртуальной машины просто указывает, что сигнал 3 был получен. Маловероятно, что переход на Dalvik что-то изменит.

Выполните сшивание фотографий в потоке, отличном от пользовательского интерфейса, и убедитесь, что поток пользовательского интерфейса не ожидает завершения другого потока. Здесь может быть полезен AsyncTask.

person fadden    schedule 08.05.2015
comment
FWIW, я думаю, что проблема № 1 может быть больше, чем кажется на первый взгляд. Например, в одном из официальных примеров Google Camera2 вы найдете несколько таких при закрытии CameraDevice в onPause(), где, насколько мне известно, поверхность из TextureView все еще хороша. Однако результаты зависят от аппаратного обеспечения: некоторые устройства с Android 5.1 (N4, N7 2013) регистрируют сообщение, а другие (N5, N6) — нет. - person CommonsWare; 08.05.2015
comment
TextureView отличается от SurfaceView тем, что потребитель находится в процессе. Поверхность, связанная с TextureView, может по-прежнему быть хорошей, но это на стороне производителя. Если сторона потребителя закрывается до входа в onPause(), сообщения будут ожидаемыми. Я не знаю, почему это зависит от оборудования, если нет гонки. В любом случае сообщения безвредны, за исключением способности читать вывод logcat; они в основном полезны как индикатор того, что кто-то тратит ресурсы впустую. - person fadden; 08.05.2015