Случайный сбой OpenGL в Honeycomb с параметром Hardware Accelerated, установленным в true - PullRequest
2 голосов
/ 22 июня 2011

Я испытываю большую проблему на Android Honeycomb 3.0 (Acer Iconia).Я не использую представление OpenGL, я только устанавливаю в манифесте

android:hardwareAccelerated="true"

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

06-22 10:13:53.510: ERROR/libEGL(951): call to OpenGL ES API with no current context (logged once per thread)
06-22 10:14:03.150: ERROR/InputDispatcher(113): channel '4098b530 com.mycompany.myapp/com.mycompany.myapp.FolderActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
06-22 10:14:03.150: ERROR/InputDispatcher(113): channel '4098b530 com.mycompany.myapp/com.mycompany.myapp.FolderActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
06-22 10:14:03.150: ERROR/InputDispatcher(113): channel '409d30e0 com.mycompany.myapp/mycompany.myapp.GalleryActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
06-22 10:14:03.150: ERROR/InputDispatcher(113): channel '409d30e0 com.mycompany.myapp/mycompany.myapp.GalleryActivity (server)' ~ Channel is unrecoverably broken and will be disposed!

Когда я установил это, у меня нет сбоя, но оно очень запаздывает:

android:hardwareAccelerated="false"

1 Ответ

1 голос
/ 23 июня 2011

Хорошо, ребята, я нашел решение :) Я обновил свою вкладку до Android 3.1, которая выдала мне настоящую ошибку OutOfMemoryError. Я размещал свой фон по нажатию кнопки. Так что теперь я делаю

WeakReference<BitmapDrawable>

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

Надеюсь, это поможет вам, бедные разработчики 3.0 ^^

Edit: вот класс, который я создал для управления кешем:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.drawable.BitmapDrawable;

public class BitmapDrawableCache {

    private static BitmapDrawableCache                 instance = null;
    WeakHashMap<String, WeakReference<BitmapDrawable>> cache;

    private BitmapDrawableCache() {
        cache = new WeakHashMap<String, WeakReference<BitmapDrawable>>();
    }

    public synchronized static BitmapDrawable get(String drawablePath) {
        if (instance == null) {
            instance = new BitmapDrawableCache();
        }

        BitmapDrawable bmd = null;
        WeakReference<BitmapDrawable> wr0 = instance.cache.get(drawablePath);
        if (instance.cache.get(drawablePath) != null) bmd = wr0.get();

        if (bmd == null) {
            WeakReference<BitmapDrawable> wr = new WeakReference<BitmapDrawable>(new BitmapDrawable(drawablePath));
            instance.cache.put(drawablePath, wr);
            bmd = wr.get();
        }

        return bmd;

    }

    public synchronized static BitmapDrawable get(Bitmap bitmap) {

        String drawableName = "_bitmap_" + bitmap.hashCode();

        if (instance == null) {
            instance = new BitmapDrawableCache();
        }

        BitmapDrawable bmd = null;
        WeakReference<BitmapDrawable> wr0 = instance.cache.get(drawableName);
        if (instance.cache.get(drawableName) != null) bmd = wr0.get();

        if (bmd == null) {
            WeakReference<BitmapDrawable> wr = new WeakReference<BitmapDrawable>(new BitmapDrawable(bitmap));
            instance.cache.put(drawableName, wr);
            bmd = wr.get();
        }

        return bmd;

    }


    //Get BitmapDrawable in cache with options to reduce its size
    public synchronized static BitmapDrawable get(String drawableName, Options options) {
        if (instance == null) {
            instance = new BitmapDrawableCache();
        }

        BitmapDrawable bmd = null;
        WeakReference<BitmapDrawable> wr0 = instance.cache.get(drawableName);
        if (instance.cache.get(drawableName) != null) bmd = wr0.get();

        if (bmd == null) {
            File f = new File(drawableName);
            WeakReference<BitmapDrawable> wr = new WeakReference<BitmapDrawable>(new BitmapDrawable(instance.decodeFile(f, options)));
            instance.cache.put(drawableName, wr);
            bmd = wr.get();
        }

        return bmd;

    }  


  //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f, Options o2){
        try {
            //Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);

            int scale=1;
            //The new size we want to scale to
            final int REQUIRED_SIZE=70;

            //Find the correct scale value. It should be the power of 2.
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }

            //Decode with inSampleSize
           // BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    }

}
...