Отмена привязки drawables onPause() вызывает невосприимчивую обратную навигацию и пропуск этого шага вызывает переполнение памяти

Я использую изображение в качестве фона для всех своих действий, но оно вызывает проблему переполнения памяти и приводит к сбою приложения. Теперь я отвязываю свои рисунки при паузе () и при уничтожении () в своей деятельности, и теперь при нажатии кнопки «Назад» отображается пустой экран. Итак, как я могу избежать этого, не используя дополнительную память.

    protected void onPause(){
    super.onPause();
    unbindDrawables(findViewById(R.id.login_root));
}

protected void onDestroy() {
        unbindDrawables(findViewById(R.id.login_root));
        super.onDestroy();
      }

private void unbindDrawables(View view) {
    System.gc();
    Runtime.getRuntime().gc();
    if (view.getBackground() != null) {
    view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
        unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
    ((ViewGroup) view).removeAllViews();
    }

Первоначально я раздувал свой макет с помощью android:background="@drawable/", что всегда вызывало ошибку переполнения памяти, говорящую о том, что виртуальная машина не позволит нам выделить 10 МБ (прибл.). Теперь я получаю растровое изображение из этого рисунка без масштабирования и привязки это во время выполнения. Теперь он говорит, что виртуальная машина не позволит нам выделить 5 МБ (прибл.) без использования unbindDrawables (..). Очевидно, что качество отображаемого фонового изображения уменьшилось, но я не могу понять, что если я использую png размером 13 КБ, как JVM требует 5 или 10 МБ места для обработки запроса?

Я переместил свои операторы макета из метода onCreate() в метод onResume(), но при нажатии кнопки «Назад» приложению снова не хватает памяти.

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

  protected void onResume(){
        setContentView(R.layout.home);
        Bitmap bmp;
        ImageView background = (ImageView)findViewById(R.id.iv_home_background);
        InputStream is = getResources().openRawResource(R.drawable.background);
        bmp = BitmapFactory.decodeStream(is);
        background.setImageBitmap(bmp);

         super.onResume();
    }

 protected void onPause(){
        super.onPause();
        unbindDrawables(findViewById(R.id.home_root));
    }


 private void unbindDrawables(View view) {
        System.gc();
        Runtime.getRuntime().gc();
        if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
        ((ViewGroup) view).removeAllViews();
        }
    }

person Atinder    schedule 12.09.2012    source источник
comment
Помните, что если вызывается onDestroy(), то onPause() также вызывается раньше.   -  person Jack Satriano    schedule 12.09.2012
comment
отвязать только в onPause(), как заявил @JohnSatriano. Но все же покажите нам свою функцию onResume   -  person Sherif elKhatib    schedule 12.09.2012
comment
Я не переопределял функцию «Возобновить». Совершенно не представляю, что там делать.   -  person Atinder    schedule 13.09.2012
comment
Я внес изменения в свой код onResume(), но это приводит к сбою моего приложения.   -  person Atinder    schedule 13.09.2012
comment
Изображение PNG сжато, но для отображения система должна хранить его в памяти в несжатом виде, поэтому ему требуется 3 или — с прозрачностью — 4 байта на пиксель. Это 1,2 МБ для изображения размером 640x480 пикселей.   -  person Ridcully    schedule 17.09.2012


Ответы (2)


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

person Atinder    schedule 17.09.2012

Вы вызываете GC для каждого дополнительного представления. Попробуйте вызвать его только один раз, когда все отвязки будут выполнены.

unbindDrawables(findViewById(R.id.login_root));
System.gc();

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

Также имейте в виду, что размеры файлов png не имеют ничего общего с растровым изображением в памяти. Вот дополнительная информация об этом http://developer.android.com/training/displaying-bitmaps/index.html

person Moxor    schedule 16.09.2013