2013-03-21 11 views
9

moim app głównym celem jest wyświetlanie obrazów w następujący sposób, jak pokazano na obrazieAndroid Bitmap.createScaledBitmap rzuca java.lang.OutOfMemoryError głównie na Jelly Bean 4.1

enter image description here

private void setSelectedImage(int selectedImagePosition) 
{ 

    BitmapDrawable bd = (BitmapDrawable) drawables.get(selectedImagePosition); 
    Bitmap b = Bitmap.createScaledBitmap(bd.getBitmap(), (int) (bd.getIntrinsicHeight() * 0.9), (int) (bd.getIntrinsicWidth() * 0.7), false); 
    selectedImageView.setImageBitmap(b); 
    selectedImageView.setScaleType(ScaleType.FIT_XY); 

} 

Szczegółowy kod można znaleźć here

jest wyjątek w następującej pozycji

Bitmap b = Bitmap.createScaledBitmap(bd.getBitmap(), (int) (bd.getIntrinsicHeight() * 0.9), (int) (bd.getIntrinsicWidth() * 0.7), false); 

Powyższa funkcja jest wywoływana z onItemSelected. ** Aplikacja nadal działa dobrze w wersjach 2.2 i 2.3, ale natychmiast rzuca wyjątek na 4.1 Powyższy kod działa poprawnie, ale generuje następujący wyjątek. Nie widziałem żadnych awarii w wersjach 2.2 i 2.3, ale to immedidately zawiesza się w 4.1 Czy istnieje jakaś istotna różnica w zarządzaniu pamięcią w żelkach? **:

java.lang.OutOfMemoryError 
AndroidRuntime(2616): at android.graphics.Bitmap.nativeCreate(Native Method) 
AndroidRuntime(2616): at android.graphics.Bitmap.createBitmap(Bitmap.java:640) 
AndroidRuntime(2616): at android.graphics.Bitmap.createBitmap(Bitmap.java:586) 
AndroidRuntime(2616): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:466) 
AndroidRuntime(2616): at com.rdx.gallery.GalleryDemoActivity.setSelectedImage(GalleryDemoActivity.java:183) 
+0

Jaki rozmiar ma szerokość i wysokość mapy bitowej? –

+0

szerokość i wysokość bitmapy to 363X387 – RDX

+0

Myślę, że problem jest wybranyImageView.setScaleType (ScaleType.FIT_XY); –

Odpowiedz

13

http://www.youtube.com/watch?v=_CruQY55HOk. Po danych pikseli andorid 3.0 bitmapy są przechowywane na stercie. Wygląda na to, że przekraczasz rozmiar pamięci sterty. Tylko dlatego, że Twoja aplikacja wymaga dużej sterty, nie używaj dużych stert. Więcej wielkości sterty, bardziej regularnych śmieci. Film ma dobre objaśnienie tematu.

Przeprojektuj mapy bitowe, gdy nie są używane. Wyrzucanie śmieci na stertach odbywa się za pomocą mojego znacznika i zamiatania, więc po ponownym przetworzeniu bitmapy jest to pamięć wolna. Więc rozmiar sterty nie wzrośnie i zabraknie pamięci.

bitmap.recycle(); 

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html. Dokumentacja na temat skutecznego ładowania bitmap. Rzuć okiem na ładowanie wersji zmniejszonej w pamięci.

Oprócz tego można użyć Universal Image Loader. https://github.com/nostra13/Android-Universal-Image-Loader.

https://github.com/thest1/LazyList. Leniwe ładowanie zdjęć.

Obie używają buforowania.

+0

przy użyciu bitmap.recycle() z nieużywanych acutally pomógł. – RDX

+0

czy to rozwiązało twój problem? – Raghunandan

+0

Użyta bitmap.recycle dla nieużywanych bitmap. Teraz nie ma więcej awarii w tym module. Dzięki – RDX

4

Próbujesz uzyskać dostęp do większej ilości pamięci niż masz. Spróbuj użyć

BitmapFactory.Options opts=new BitmapFactory.Options(); 
     opts.inDither=false;      
     opts.inSampleSize = 8;     
     opts.inPurgeable=true;     
     opts.inInputShareable=true;    
     opts.inTempStorage=new byte[16 * 1024]; 

Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h1) 
     , 65,65, true), 

Również spojrzeć na poniższe linki, aby zwiększyć pamięć

http://developer.android.com/reference/android/R.styleable.html#AndroidManifestApplication_largeHeap

Detect application heap size in Android

EDIT 1

spróbować użyć nostras downloader obrazu, można użyć go do pokaż obraz w lokalnej pamięci. I zarządza pamięć bardzo dobrze ...

https://github.com/nostra13/Android-Universal-Image-Loader

+0

i zaktualizowałem pytanie, proszę mieć relook – RDX

+0

próbowałem tego, ale nie działało albo – RDX

+0

Pls spojrzeć na edycję, sugeruję, aby użyć biblioteki nostras – Talha

25

Ważne jest, aby pamiętać, że następujący kod może spowodować wyjątek:

Bitmap bitmap = Bitmap.createScaledBitmap(oldBitmap, newWidth, newHeight, true); 
oldBitmap.recycle(); 

Właściwa jest:

Bitmap bitmap = Bitmap.createScaledBitmap(oldBitmap, newWidth, newHeight, true); 
if (oldBitmap!= bitmap){ 
    oldBitmap.recycle(); 
} 

ponieważ dokumentacja mówi:

Jeżeli określona szerokość i wysokość są tak samo jak bieżąca szerokość i wysokość źródła btimap, źródłowa bitmapa jest zwracana, a teraz Nowa bitmapa jest tworzona.

+0

Ten kod może wywoływać wyjątki, jeśli mapa bitowa została już z jakiegokolwiek powodu poddana recyklingowi, musisz dodać to do czeku: &&! OldBitmap.isRecycled() –

+0

W jakiej implementacji klasy Bitmap jest to konieczne? Ponieważ nie w 5.1.0_r1, ponieważ metoda sprawdza to istelf: "if (! MRecycled && mFinalizer.m NativeBitmap! = 0)" http://grepcode.com/file/repository.grepcode.com/java/ext/com .google.android/android/5.1.0_r1/android/graphics/Bitmap.java # Bitmap.recycle% 28% 29 – Malachiasz

Powiązane problemy