2013-01-16 10 views
17

Mam Android app z 3 acitivtys:Out of Memory Error podczas załadunku bitmaps

A1 - rozpoczyna -> A2 - rozpoczyna -> A3 - kiedy skończył proces: rozpoczyna -> A1

(więc nie "Finish();". app i rozpocząć kolejne activitys z "startActivity (..);" cały czas po userinteraction)

tak w tych 3 działaniach istnieje pętla. Na każdej działalności, i wyświetlić 3-9 zdjęć, znajdujących się na karcie SD, które załadować z moim następującą funkcją:

try 
{ 
    Uri selectedImageURI = Uri.parse(strImagePath); 
    File imgFile = new File(getRealPathFromURI(selectedImageURI, c)); 
    Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath()); 
    ivTmp.setImageBitmap(myBitmap); 
}catch (Exception e) 
{ 
    return null; 
} 

To wszystko działa. ale czasami (po pętli kilka razy przez moich activitys), moi awarii aplikacji ..

logcat mówi mi:

01-16 13:42:15.863: DEBUG/dalvikvm(23161): GC_BEFORE_OOM freed 10K, 9% free 59019K/64400K, paused 29ms, total 30ms 
01-16 13:42:15.863: ERROR/dalvikvm-heap(23161): Out of memory on a 8018704-byte allocation. 
01-16 13:42:15.863: ERROR/AndroidRuntime(23161): FATAL EXCEPTION: main 
     java.lang.OutOfMemoryError 
     at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502) 
     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:355) 
     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785) 
     at android.content.res.Resources.loadDrawable(Resources.java:1965) 
     at android.content.res.Resources.getDrawable(Resources.java:660) 
     at android.widget.ImageView.resolveUri(ImageView.java:616) 
     at android.widget.ImageView.setImageResource(ImageView.java:349) 
     at <MyApp>.MyActivity$6.run(MyActivity.java:143) 
     at android.os.Handler.handleCallback(Handler.java:725) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:5039) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:511) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
     at dalvik.system.NativeStart.main(Native Method) 

Ktoś może dać mi jakieś wskazówki, jak radzić sobie z awarii? Może to dlatego, że moje działania są ustawione na stan "wstrzymano", zamiast je poprawnie zamknąć?

+1

spróbuj wywołać .recycle() na swoich bitmapach w OnPause(). i załaduj je on onResume() nie onCreate(). – pumpkee

+0

czy można to zrobić w lepszy sposób? jak, jeśli wszystkie moje bitmapy znajdują się w linelayoutie, a następnie wywołują llMain.recycle(), czy coś w tym stylu? – Prexx

+0

Można utworzyć ArrayList , do której dodaje się każdą bitmapę, którą wczytuje się i przetwarza przez nią pętlę. Kolejna rzecz ogólna: zagraj z próbną wielkością obrazu. Nie wiesz, do czego służy twoja aplikacja, ale po prostu pokazuje bitmapę na ekranie, przez większość czasu wystarczy, aby wypróbować i zaoszczędzić pamięć. Zobacz: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html – pumpkee

Odpowiedz

31

do szybkiej i taniej można dodać

android:largeHeap="true" w oczywisty tagu aplikacji

link here:

I twarz problemu OOM na moim stole w Kindle i Nook

Heap size (large) 
android:largeHeap="true" 
tam

specyfikacja jest wspomniano o użyciu większego sterty link here:

EDIT: stosowanie techniki buforowania bitmapy link here

+1

Widziałem to również w innym pytaniu, nie będzie działać. – Prexx

+1

Buforowanie bitmap bardzo mi pomogło! Dzięki! :) – Prexx

+1

Dziękuję. Ta flaga android: largeHeap w manifeście rozwiązała problem dla mnie. –

0

Tak android robi natychmiast zniszczyć działania, gdy nie są widoczne dla użytkownika, ale istnieje szereg metod cyklu życia, które są wywoływane w zależności od aktualnego stanu. Sprawdź http://developer.android.com/guide/components/activities.html#Lifecycle

Możesz spróbować zakończyć działania w trybie onStop() lub onDestroy(), ponieważ będą one wywoływane, gdy aktywność nie jest widoczna i gdy system odpowiednio wyczerpuje pamięć. :-)

+0

Próbowałem zakończyć działania, ale w rezultacie wróciłem do aktywności. Przykład: im na A3 i chcę iść na A1: wzywam startIntenta (A1) i kończę -> im na A2 ..:/ – Prexx

+0

Ok , więc myślę, że jeśli przesłonisz onStop() dla każdego działania i umieścisz finish() w tej metodzie, to powinno zakończyć to działanie i zwolnić zasoby zamiast systemu przechowującego je w pamięci po rozpoczęciu następnego działania. Upewnij się, że finish() nie kończy bieżącego działania. – Broo

0

Jest to spowodowane wysoką rozdzielczością obrazu trzeba skalowania bitmapy należy użyć następującego kodu

Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath()); 

    int h = 100; // height in pixels 
    int w = 100; // width in pixels 
Bitmap photoBitMap = Bitmap.createScaledBitmap(myBitmap,h, w, true); 
ivTmp.setImageBitmap(photoBitMap); 
2

miałem podobny problem podczas wyświetlania obrazów o wysokiej rozdzielczości. Przeszukałem i zastosowałem wszystkie rozwiązania bitmapowe Android podane w http://developer.android.com/training/displaying-bitmaps/index.html i następujące buforuje mekanizm w linku. ale żaden z nich nie działa. nigdzie nie ma żadnego właściwego rozwiązania. Wtedy zorientowałem się, że problem polega na tym, że nie mogłem użyć struktury foldera do rysowania w prawo. Utrzymywałem obrazy o wysokiej rozdzielczości w folderach mdpi i hdpi. to powoduje, że Android skaluje obrazy do ultra rozmiarów. Obraz o wielkości 100 kb powodował zwiększenie pamięci o 20 MB dzięki sekcji android monitor/memory. , więc dodałem te zdjęcia w rozdzielczości ultra do folderu xxhdpi, a następnie został nagle naprawiony.następnie mój suwak obrazu działa bezbłędnie

Powiązane problemy