2015-01-05 1 views
2

Я получаю мои растровый как и из XML:Android говорил мне мои растровый перерабатываются, прежде чем я на самом деле возвращаю его

//Get bitmap from drawable 
bd = (BitmapDrawable) view.getResources().getDrawable(R.drawable.backgrounds); 
backgrounds = bd.getBitmap(); 

//Do required work with bitmap (Will just use a log statement here for testing 
Log.v("NewTag","Testing: "+bd.getBitmap().getPixel(0, 0)); 

//Now recycle this large bitmap 
bd.getBitmap.recycle(); 
bd=null; 
backgrounds.recycle(); 
backgrounds=null; 

Первый раз, когда я запускаю этот код, все хорошо. Однако, когда я выхожу из своего приложения (используя задний ключ), перезагрузите приложение, оно может или может не работать. Иногда я получаю сообщение об ошибке:

Can't call getPixel() on a recycled bitmap

Почему? Я еще не переработал его. Или, точнее, похоже, что это не воссоздание растрового изображения и запоминание повторного использования с последнего времени.

Эта проблема не возникает, если я использую BitmapFactory для получения растрового изображения (к сожалению, я не могу этого сделать, поскольку мне нужно получить это конкретное растровое изображение из псевдонима XML).

Также до установки Lollipop это работало нормально (пока у меня было bd = null).

Я был в этой проблеме в течение 2 дней подряд, поэтому, если бы кто-нибудь мог пролить свет на нее, я был бы очень благодарен.

Редактировать

Я попытался @ предложение AGA о просто не рециркуляции/обнуления бд, но это не имеет никакого значения. Растровое изображение по-прежнему «уже» переработано, как только оно было восстановлено (опять же, с перерывами).

Кроме того, при входе примерно так:

Log.v("NewTag","Backgrounds: "+backgrounds); 

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

enter image description here

ответ

2

Интересный вопрос. Я уверен, в Android были некоторые идеи по оптимизации.

Если вы сделать нужны растровые изображения в XML:

Resources res = new Resources(getAssets(), new DisplayMetrics(), new Configuration()); 

    bd = (BitmapDrawable) res.getDrawable(R.drawable.bitmap_drawable); 
    backgrounds = bd.getBitmap(); 

    ...... 

    bd.getBitmap().recycle(); 
    bd=null; 
    backgrounds.recycle(); 
    backgrounds=null; 

Опционально, вы можете сначала попытаться получить Bitmap от стандартного getResources() и только затем создать экземпляр нового экземпляра ресурса.

Если вы не нужны растровые изображения в XML:

Bitmap backgrounds = BitmapFactory.decodeResource(getResources(), R.drawable.test_image); 

, чтобы получить изображение и

backgrounds.recycle(); 
backgrounds=null; 

переработать его.

Надеюсь, это поможет.

+0

Спасибо @KonstantinLoginov, но, пожалуйста, см. Это (цитируется из вопроса): «Эта проблема не возникает, если я использую BitmapFactory для получения растрового изображения (к сожалению, я не могу этого сделать, поскольку мне нужно получить это конкретное растровое изображение из псевдоним XML). " – Zippy

+0

@ Почему вы еще не решили решение? У меня та же проблема. Я удаляю весь код recycles в настоящий момент и жду ответа – JayVDiyk

+2

@ Zippy my bad - я посмотрю, могу ли я обойти это. –

5

Класс Resources имеет caches for resources loaded from your APK. Когда вы перерабатываете Drawable и Bitmap, вы разрушаете кешированные объекты. Кассы Resources не могут знать об этом, поэтому они с радостью возвращают вам тот же самый объект в следующий раз, когда вы попросите этот ресурс.

Когда ваш процесс приложения умирает, все состояние памяти теряется, в том числе кеш ресурсов, поэтому все будет работать снова (один раз). Обратите внимание, что «выход из приложения или уничтожение активности не обязательно означает, что ваш процесс умрет.

+1

Не доходит до закрытия приложения означает, что приложение полностью закрыто? – JayVDiyk

+0

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

+1

@JayVDiyk: Нет, это не так. В этой ситуации ваша «активность» будет уничтожена, но ваш * процесс *, скорее всего, все еще жив. Android поддерживает его для ускорения будущих запусков одного и того же приложения. Это то, что известно как «кешированный процесс» или «пустой процесс» в статистике памяти. Система автоматически очищает такие процессы по мере необходимости. Вы можете узнать больше о жизненном цикле процесса здесь: http://developer.android.com/guide/topics/processes/process-lifecycle.html –

0

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

По моему мнению, решение должно соответствовать save the bitmap to internal storage и reload it from storage, когда это необходимо.

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

+0

Существует также накладные расходы по повторной загрузке этого изображения снова и снова ... кажется ненужным. –

Смежные вопросы