ImageView в приложении порождения Android для катастрофического отказа

У меня есть приложение, которое использует фотографии, сохраненные или на SD-карте или на непосредственно по телефону.

У меня есть 2 Операции, которые, кажется, имеют некоторую проблему (Acitives для Просмотра и Редактирования записи). Рекордные ссылки сингла фотография путем хранения URI, который дает местоположение связанной фотографии.

Когда я нажимаю на свое действие Представления, я передаю URI и затем устанавливаю ImageView с помощью URI. Когда в Действии Представления, у меня есть пункт меню, который позволяет Вам достигать Действия Редактирования. Когда Вы нажимаете Edit, я снова передаю URI фотографии и устанавливаю ImageView с помощью URI. Обе из этих операций дисплей, прекрасный самостоятельно.

Однако, когда я нажимаю Кнопку "Назад" для перемещения от Редактирования до Представления, сбоев приложения. Первоначально катастрофический отказ был Исключением OutOfMemory. Я закончил это исключение путем добавления вызова к ((BitmapDrawable)mImageView.getDrawable()).getBitmap().recycle() в onPause функционируют в обеих операциях.

С перерабатывать кодом на месте, перемещениями выполнения от Редактирования назад для Просмотра, и затем просто отказывает где-нибудь. Я ступил через функции жизненного цикла, и выполнение удается успешно, за исключением onCreate. Выполнение никогда не достигает onCreate снова.

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

Вот начальное отслеживание стека, когда катастрофический отказ происходит:

Thread [<3> main] (Suspended (exception RuntimeException))  
    ViewRoot.draw(boolean) line: 1356   
    ViewRoot.performTraversals() line: 1097 
    ViewRoot.handleMessage(Message) line: 1613  
    ViewRoot(Handler).dispatchMessage(Message) line: 99 
    Looper.loop() line: 123 
    ActivityThread.main(String[]) line: 4203    
    Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
    Method.invoke(Object, Object...) line: 521  
    ZygoteInit$MethodAndArgsCaller.run() line: 791  
    ZygoteInit.main(String[]) line: 549 
    NativeStart.main(String[]) line: not available [native method]  

После этого отслеживания стека, если я продолжаю продвигать, "Переступают" в Eclipse, отслеживание стека заканчивается как это:

Thread [<3> main] (Suspended)   
    ThreadGroup.uncaughtException(Thread, Throwable) line: 884  
    NativeStart.main(String[]) line: not available [native method]  
1
задан Janusz 6 July 2010 в 06:56
поделиться

2 ответа

Я нашел способ решить эту проблему.

Я смог найти это другое решение отчасти благодаря ответу Януша. В моих классах View и Edit я добавил приватную переменную класса Bitmap (mBitmap). В onCreate я получаю и сохраняю URI для местоположения моего изображения. В onPause я перерабатываю битмап. В onResume я обновил эту функцию, чтобы использовать новую переменную класса mBitmap (и я уверен, что есть лучший способ настройки Bitmap, так что все не стесняйтесь указать на него). Кроме того, с этим новым кодом я столкнулся с проблемой сбоя в классе Edit. Если вы заходили в Edit, а затем нажимали кнопку "Home", приложение аварийно завершало работу. Я обнаружил, что решением этой проблемы является установка Bitmap представления изображения на null в Edit.onPause. Проблема заключалась в том, что imageView сохранял указатель на битмап, даже после того, как я переработал битмап. См. Ошибка Android "Trying to use recycled bitmap?":

protected void onResume()
{
    mBitmap = null;
    try
    {
        mBitmap = Bitmap.createBitmap(Media.getBitmap(this.getContentResolver(), mPicUri));
    }
    catch(Exception e)
    {}

    mImageView.setImageBitmap(mBitmap);
    mImageView.setAdjustViewBounds(true);
    mImageView.setMaxHeight(100);      //purposely showing image as 100x100 picture
    mImageView.setMaxWidth(100);
    mImageView.invalidate();

    super.onResume();
}

protected void onCreate()
{
    mPicUri = //the picuture location URI
}

protected void onPause()
{
    mBitmap.recycle();
    mImageView.setImageBitmap(null);  //in my Edit class
}
1
ответ дан 2 September 2019 в 23:16
поделиться

Если вы переходите с первого действия на второе, первое действие будет приостановлено. Затем метод onPause перезапустит растровое изображение.
Если вы переключитесь с «Второе действие» на «Первое», первое действие уже существует, и нет необходимости снова вызывать onCreateMethod. Вместо этого вызывается только метод onResume, сообщающий активности, что она снова отображается на экране. В этот момент imageview пытается нарисовать изображение на экране, но из-за того, что изображение переработано, ваше приложение вылетает.

Если вам действительно нужно переработать растровое изображение, вы должны сбросить его в методе onResume перед вызовом метода super onResume вашего действия.

1
ответ дан 2 September 2019 в 23:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: