2016-07-05 2 views
0

Я пытаюсь загрузить изображение из большой галереи (около 30 МБ-70 МБ). Проблема, которую я держать облицовкой:Crash OutOfMemoryError при попытке загрузить большое изображение из галереи

FATAL EXCEPTION: main Process: com.parse.starter, PID: 29795
java.lang.OutOfMemoryError: Failed to allocate a 1866240012 byte allocation with 2323392 free bytes and 380MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:649) at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:867) at com.parse.starter.AddPhotosActivity.onActivityResult(AddPhotosActivity.java:151) at android.app.Activity.dispatchActivityResult(Activity.java:6428) at android.app.ActivityThread.deliverResults(ActivityThread.java:3695) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) at android.app.ActivityThread.-wrap16(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Вот мой код (строка 151, как указано выше, в журнале аварии) имеет комментарий прямо над ним. В принципе, конечной целью является то, что я хочу сразу определить, имеет ли выбранное изображение больше 10 МБ. Если это так, то отправьте тост, если нет, затем приступайте к сохранению изображения на бэкэнд.

if (requestCode == SELECT_PHOTO && resultCode == RESULT_OK) 
{ 
    Uri uri = data.getData(); 
    File f = new File(uri.getPath()); 

    try 
    { 
     // LINE BELOW IS THE LINE 151, ERROR CRASH 
     Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); 
     if (bitmap.getByteCount() > 10485760) 
     { 
      Toast.makeText(AddPhotosActivity.this, "That file is too large to attach to a Grievance, please try again!", Toast.LENGTH_SHORT).show(); 
     } 
     else 
     { 
      mImageOne.setImageBitmap(bitmap); 
      SaveImageOne(bitmap); 
     } 

    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 
+1

BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bm = BitmapFactory.decodeFile (picPath, опции); попробуйте это – Nisarg

+1

Смотрите это: https://developer.android.com/training/displaying-bitmaps/load-bitmap.html – marcinj

+0

Пожалуйста, найдите свое исключение в следующий раз, есть много вопросов, связанных с этим – tyczj

ответ

0

java.lang.OutOfMemoryError бывает в случае загрузки изображения. Потому что память телефона имеет определенные ограничения. Поэтому вместо загрузки изображения напрямую используйте какую-то библиотеку, например, picasso и т. Д. И загружайте изображение в соответствии с размером, который вам не нужен в исходных размерах, это уменьшит потребление памяти.

picasso

И заменить

mImageOne.setImageBitmap(bitmap); 

с

Picasso.with(context).load(uri).resize(50, 50).centerCrop().into(mImageOne); 

// здесь 50,50 это новое измерение, centercrop является scaletype

+0

. Спасибо, но это не та строка, с которой я столкнулся. – Jamie22

+0

Вы пробовали это? Очевидно, это не та строка, которая вызывает проблему. Но это код, который загружает ваше изображение в режиме просмотра изображений. Перед изменением размера или сжатием. Поэтому память телефона заполняется. Эта библиотека не только для изменения размера, но и для повторного использования представлений для оптимизации памяти. Вы заметили свой логарифм. В соответствии с этим в вашем коде отсутствует ошибка. Но есть код, который отвечает за исключение из памяти. –

-1

вы можете проверить файл перед с :

File file = new File(uri.getPath()); 

// Get length of file in bytes 
long fileSizeInBytes = file.length(); 

//10485760 will work for your phone, but not for all 
if (fileSizeInMB > 10485760) { 
    ... 
}¸ 

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

Я не уверен, что вы хотите достичь, но если вы хотите, чтобы загрузить изображение из галереи или из камеры, пожалуйста, проверьте этот учебник: http://www.theappguruz.com/blog/android-take-photo-camera-gallery-code-sample

+0

Просто попробуйте сделать мое приложение получить ссылку на изображение, выбранное в галерее, и загрузить его. У меня не было никаких проблем или сбоев, пока я не начал собирать изображения, которые были 10mb + – Jamie22

-1

на основе материалов, о которых идет речь, кажется, вы первый хотите проверить размер файла перед его обработкой. Вы можете просто сделать это путем создания объекта File, что-то вроде следующий:

File file = new File("<<Provide full file path>>"); 
long length = file.length(); 

if (length > 10485760) 
{ 
      Toast.makeText(AddPhotosActivity.this, "That file is too large to attach to a Grievance, please try again!", Toast.LENGTH_SHORT).show(); 
} 

Подробнее о апи на URL

Надеются, что это помогает.

Cheers!

+0

Это тот самый, который имеет для меня наибольший смысл, но как мне получить путь от uri? Я попробовал что-то вроде этого, не повезло. Uri uri = data.getData(); Файл file = новый файл (uri.getPath()); – Jamie22

+0

@ Jamie22 - Где находятся файлы на устройстве? –

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