Подтвердить что ты не робот

Android как обработать исключение из памяти

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

4b9b3361

Ответ 1

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

Ответ 2

Не удается обработать OutOfMemory. Как вы думаете?

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

OutOfMemory необходимо предотвратить, а не обрабатывать после возникновения.

Ответ 3

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

Вы также можете добавить блок catch try, чтобы поймать Error или OutOfMemoryError, но это было бы слишком поздно.

Работа с большими количествами растровых изображений или большими растровыми изображениями действительно сложна в приложениях для Android. Вы найдете несколько советов по этому вопросу в этой статье от Ромена Гая.

Вы также можете позаботиться о загрузке растровых изображений непосредственно в нужное разрешение, указав размер выборки в BitmapFactory.options, который вы предоставляете BitmapFactory.decode *().

Ответ 4

Я начал пробовать эту процедуру, которая загружает jpeg в ImageView и проверяет Out of Memory и перемасштабирует до тех пор, пока он не подходит.

 static public boolean tryJpegRead(ImageView imageView, File fn){
 if (!fn.exists()){ 
     Log.d("ANDRO_ASYNC",String.format("missing file %s",fn.getAbsolutePath()));
     return false;
 }
 BitmapFactory.Options o = new BitmapFactory.Options();
    for (int i = 1; i<10; i++){
        o.inSampleSize = i;
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(fn.getAbsolutePath(), o);
        int h = o.outHeight;
        int w = o.outWidth;
        Log.d("ANDRO_ASYNC",String.format("going in h=%d w=%d resample = %d",h,w,o.inSampleSize));
        o.inJustDecodeBounds = false;
        try{
            imageView.setImageBitmap(
                Bitmap.createScaledBitmap(
                        BitmapFactory.decodeFile(fn.getAbsolutePath(), o), 
                        w, 
                        h, 
                        true)); 
            return true; // only happens when there is no error
        }catch(OutOfMemoryError E){
            Log.d("ANDRO_ASYNC",String.format("catch Out Of Memory error"));
    //      E.printStackTrace();
            System.gc();
        }           
    }
    return false;
}

Ответ 5

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

public static BitmapFactory.Options getBitmapOptionsWithoutDecoding(String url){
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(url, opts);
    return opts;
}

public static int getBitmapSizeWithoutDecoding(String url){
    BitmapFactory.Options opts = getBitmapOptionsWithoutDecoding(url);
    return opts.outHeight*opts.outWidth*32/(1024*1024*8);
}

//ref:http://stackoverflow.com/questions/6073744/android-how-to-check-how-much-memory-is-remaining
public static double availableMemoryMB(){
    double max = Runtime.getRuntime().maxMemory()/1024;
    Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
    Debug.getMemoryInfo(memoryInfo);
    return (max - memoryInfo.getTotalPss())/1024;
}

public static final long SAFETY_MEMORY_BUFFER = 10;//MB

public static boolean canBitmapFitInMemory(String path){
    long size = getBitmapSizeWithoutDecoding(path);
    Log.d(TAG, "image MB:"+size);
    return size <= availableMemoryMB() - SAFETY_MEMORY_BUFFER;
}

ref: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Ответ 6

Если у вас есть большие изображения, такие как фон или аналогичный, простой способ предотвратить Out Of Memory - перемещать изображения с drawable-xhdpi в drawable-nodpi, но будьте осторожны, это будет загружать растровое изображение без каких-либо изменений. Хороший способ следует использовать BitmapFactory.options для соответствия вашей потребности

Ответ 7

try {
// All methods here....
} catch(OutOfMemoryException e){
// Show an AlertDialog with "Memory is full" title
// If press ok then starts the process again..
}

Ответ 8

Использовать android: allowBackup = "true", android: hardwareAccelerated = "false" и android: largeHeap = "true" для решения этой проблемы

 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher"
        android:hardwareAccelerated="false"
        android:largeHeap="true"
        android:theme="@style/AppTheme">