Chcę pokazać obraz bitmapowy w ImageView z karty SD, która jest już zapisana. Po uruchomieniu moja aplikacja ulega awarii i pojawia się błąd OutOfMemoryError :
(java.lang.OutOfMemoryError: Nie udało się przydzielić alokacji 23970828 bajtów z 2097152 wolnymi bajtami i 2 MB do OOM)
Nie mam pojęcia ani dlaczego brak pamięci. Myślę, że mój rozmiar obrazu jest bardzo duży, więc próbowałem go zmienić.
Iterator<String> it = imageArray.iterator();
while (it.hasNext()) {
Object element = it.next();
String objElement = element.toString();
Log.e("objElement ", " = " + objElement);
final ImageView imageView = new ImageView (getContext());
final ProgressBar pBar = new ProgressBar(getContext(), null,
android.R.attr.progressBarStyleSmall);
imageView.setTag(it);
pBar.setTag(it);
imageView.setImageResource(R.drawable.img_placeholder);
pBar.setVisibility(View.VISIBLE);
if (objElement.endsWith(mp3_Pattern)) {
Log.e("Mp3 ", " ends with ");
pBar.setVisibility(View.GONE);
imageView.setImageResource(R.drawable.audio_control);
}
if (objElement.endsWith(png_Pattern)) {
Bitmap bitmap = BitmapFactory.decodeFile(objElement);
int size = Math.min(bitmap.getWidth(), bitmap.getHeight());
int x = (bitmap.getWidth() - size) / 2;
int y = (bitmap.getHeight() - size) / 2;
Bitmap bitmap_Resul = Bitmap.createBitmap(bitmap, x, y, size, size);
Log.e("bitmap_Resul "," = "+ bitmap_Resul);
if (bitmap_Resul != bitmap) {
bitmap.recycle();
}
imageView.setImageBitmap(bitmap_Resul);
Log.e("png_Pattern ", " ends with ");
Log.e(" bitmap "," = " + bitmap);
}
holder.linearLayout.addView(imageView);
holder.linearLayout.addView(pBar);
Informacje o kocie dziennika:
08-27 14:11:15.307 1857-1857/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.tazeen.classnkk, PID: 1857
java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:812)
at android.graphics.Bitmap.createBitmap(Bitmap.java:789)
at android.graphics.Bitmap.createBitmap(Bitmap.java:709)
at android.graphics.Bitmap.createBitmap(Bitmap.java:634)
at com.example.tazeen.classnkk.AllPosts_Page$MyListAdapter.getView(AllPosts_Page.java:357)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillDown(ListView.java:698)
at android.widget.ListView.fillFromTop(ListView.java:759)
at android.widget.ListView.layoutChildren(ListView.java:1659)
at android.widget.AbsListView.onLayout(AbsListView.java:2151)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15671)
at android.view.ViewGroup.layout(ViewGroup.java:5038)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2086)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1843)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
android
android-bitmap
androidTag
źródło
źródło
Odpowiedzi:
Błąd brak pamięci to najczęstszy problem występujący w Androidzie, szczególnie w przypadku map bitowych. Ten błąd jest zgłaszany przez maszynę wirtualną Java (JVM), gdy obiekt nie może zostać przydzielony z powodu braku miejsca w pamięci, a także moduł odśmiecania nie może zwolnić miejsca.
Jak wspomniano Aleksey, w pliku manifestu możesz dodać poniższe encje
android:hardwareAccelerated="false"
,android:largeHeap="true"
będzie to działać w niektórych środowiskach.zdecydowanie powinieneś przeczytać niektóre koncepcje Deweloperów Androidów, szczególnie tutaj: Wydajne wyświetlanie map bitowych
Przeczytaj wszystkie 5 tematów i przepisz kod ponownie. Jeśli nadal nie działa, z przyjemnością zobaczymy, co zrobiłeś źle z materiałem do samouczka.
Oto niektóre z możliwych odpowiedzi na tego typu błędy w SOF
Android: BitmapFactory.decodeStream () brak pamięci w pliku 400 KB z 2 MB wolnej sterty
Jak rozwiązać problem z java.lang.OutOfMemoryError w Androidzie
Android: java.lang.OutOfMemoryError
java.lang.OutOfMemoryError
Rozwiązanie dla OutOfMemoryError: rozmiar mapy bitowej przekracza budżet maszyny wirtualnej
Edycja: Na podstawie komentarzy @cjnash
Dla każdego, kto nadal miał awarie po dodaniu tej linii, spróbuj przykleić obraz do folderu res / drawable-xhdpi / zamiast res / drawable / i może to rozwiązać problem.
źródło
próbowałeś dodać to do manifestu w aplikacjach?
android:largeHeap="true"
?lubię to
źródło
Dla mnie problem polegał na tym, że mój plik .png był dekompresowany, aby był naprawdę ogromną bitmapą w pamięci, ponieważ obraz miał bardzo duże wymiary (mimo że rozmiar pliku był niewielki).
Więc poprawka polegała na zmianie rozmiaru obrazu :)
źródło
android:hardwareAccelerated="false"
niektóre animacje, takie jak cień układu, nie działały. Ale po zmianie rozmiaru wszystkie problemy zostały rozwiązane, dziękuję! +1 za tę wskazówkę!Właściwie możesz dodać w swoim manifeście te wiersze
android:hardwareAccelerated="false"
,android:largeHeap="true"
to działa w niektórych sytuacjach, ale pamiętaj, że inna część kodu może się z tym kłócić.źródło
To powinno działać
źródło
Zmień rozmiar obrazu przed konfiguracją do ImageView w następujący sposób:
gdzie rozmiar to rzeczywisty rozmiar ImageView. Możesz osiągnąć rozmiar mierząc:
i użyj następnego rozmiaru
imageView.getMeasuredWidth()
iimageView.getMeasuredHeight()
dlascaling
.źródło
Użyj Glide Library i Override size, aby zmniejszyć rozmiar;
źródło
Mam błąd poniżej
po dodaniu
android:largeHeap="true"
w AndroidManifest.xml pozbywam się wszystkich błędówźródło
Rozwiązałem ten problem, zmieniając rozmiar obrazu do mniejszego rozmiaru. Używam formularza Xamarin. zmniejszenie rozmiaru obrazu PNG rozwiązało problem.
źródło
Rozwiązanie: 1. otwórz plik manifestu 2. wewnątrz tagu aplikacji po prostu dodaj poniżej dwóch wierszy
Przykład:
źródło
Przekonałem się, że obrazy w folderze z możliwością rysowania zostaną przekonwertowane na znacznie większy obraz na telefonach o wysokiej rozdzielczości. Na przykład obraz 200k zostanie ponownie próbkowany do wyższej rozdzielczości, takiej jak 800k lub 32000k. Musiałem to odkryć na własną rękę i do tej pory nie widziałem dokumentacji dla tej pułapki pamięci sterty. Aby temu zapobiec, umieszczam wszystko w folderze nodpi z możliwością rysowania (oprócz korzystania z „opcji” w BitmapFactory na podstawie stosu urządzeń). Nie mogę sobie pozwolić na powiększenie mojej aplikacji wieloma folderami, które można wyciągać, zwłaszcza, że zakres definicji ekranów jest teraz ogromny. Trudne jest to, że studio nie wskazuje teraz specjalnie folderu „drawable-nodpi” jako takiego w widoku projektu, po prostu pokazuje folder „drawable”. Jeśli nie będziesz ostrożny, gdy upuścisz obraz do tego folderu w studio, wygra „
Pamiętaj, aby kliknąć w oknie dialogowym folder nodpi, ponieważ widok projektu nie pokaże wszystkich folderów z możliwością rysowania osobno, tak jak kiedyś, więc nie będzie od razu widoczne, że poszło do niewłaściwego. Studio odtworzyło dla mnie wanilię „dającą się rysować” po tym, jak ją usunąłem dawno temu:
źródło
To działało dla mnie: po prostu przenieś obrazy z folderu do rysowania do drawable-hdpi.
źródło
Soluton wypróbuj to w pliku manifestu i użyj Glide Library
skompiluj „com.github.bumptech.glide: glide: 3.7.0”
android: hardwareAccelerated = "false"
android: largeHeap = "true"
Użyj tej biblioteki
Jego działanie Happy Coding
źródło
dodać to do swojego manifestu w ramach aplikacji? android: largeHeap = "true"
źródło
Też miałem problem.
To samo z większością innych powyżej. Problem jest spowodowany dużym obrazem.
Po prostu zmień rozmiar niektórych zdjęć i nie musisz zmieniać żadnego kodu.
źródło
W niektórych przypadkach (np. Operacje w pętli) moduł odśmiecania jest wolniejszy niż kod. Możesz użyć metody pomocniczej z tej odpowiedzi, aby poczekać na moduł odśmiecający .
źródło
Jestem nowicjuszem w tworzeniu Androida, ale mam nadzieję, że moje rozwiązanie pomoże, działa idealnie w moim stanie. Korzystam z Imageview i ustawiam tło na „src”, ponieważ próbuję utworzyć animację klatki. Wystąpił ten sam błąd, ale gdy próbowałem to zakodować, zadziałało
źródło
Zetknąłem się z tym problemem, gdy nie zabiłem mojej starej aktywności, przechodząc do nowej działalności. Naprawiłem to
finish();
źródło
50/100, jeśli używa się 100, oryginalna rozdzielczość może zatrzymać aplikacje na brak pamięci.
jeśli 50 lub mniej niż 100, będzie to 50% lub mniej niż 100, więc zapobiegnie to problemowi braku pamięci
źródło
Musisz zmienić rozmiar obiektu w rysunku. Jest za duży, by go wyświetlić. np. jeśli ustawiasz obraz, wypróbuj obraz z mniejszą liczbą pikseli. Mi to pasuje. Dzięki. :)
źródło
Twoja aplikacja ulega awarii, ponieważ rozmiar obrazu (w MB lub KB) jest zbyt duży więc nie przeznacza na to miejsca. Tak więc przed wklejeniem obrazu do rysowania po prostu zmniejsz rozmiar.
LUB
Możesz dodać etykietę Obserwacja w aplikacji na Manifest.xml
Po dodaniu tej aplikacji nie zawiesza się.
źródło
Mój problem rozwiązany po dodaniu
w pliku Build.Gradle
źródło
źródło
Podczas przesyłania obrazu spróbuj zmniejszyć jakość obrazu, który jest drugim parametrem mapy bitowej. To było rozwiązanie w moim przypadku. Wcześniej było 90, potem próbowałem z 60 (jak teraz w kodzie poniżej).
źródło
Wypróbuj najprostszy. Być może Twoja aplikacja ulega awarii, ponieważ rozmiar obrazu (w MB) jest zbyt duży, więc nie przeznacza na to miejsca. Więc przed wklejeniem obrazu do rysowania po prostu zmniejsz rozmiar przy pomocy dowolnego oprogramowania przeglądarki lub jeśli pobierasz obraz z galerii w czasie wykonywania, niż przed zapisaniem go skompresuj swoją mapę bitową. To zadziałało dla mnie. na pewno dla ciebie będzie.
źródło
Następnie w znaczniku aplikacji dodaj largeheapsize = "true
źródło
Przypuszczam, że chcesz użyć tego obrazu jako ikony. Jak mówi Android, twój obraz jest za duży. Wystarczy skalować obraz, aby system Android wiedział, jaki rozmiar obrazu użyć i kiedy zgodnie z rozdzielczością ekranu. Aby to zrobić, w Android Studio: 1. kliknij prawym przyciskiem myszy folder res, 2. wybierz Zasób obrazu 3. Wybierz ikonę Typ 4. Nadaj ikonie nazwę 5. Wybierz Obraz na Typ zasobu 6. Przytnij obraz Kliknij przycisk Dalej i zakończ . W swoim pliku XML lub źródłowym po prostu odwołaj się do obrazu, który będzie teraz znajdował się w folderze układu lub mipmap zgodnie z wybranym typem zasobu. Błąd zniknie.
źródło
Naprawdę nie polecam edytowania takiego manifestu
Te opcje nie powodują płynnego efektu animacji w Twojej aplikacji. Ponadto „liveData” lub zmiana lokalnego DB (Sqlite, Room) aktywują się powoli. Jest to niekorzystne dla wygody użytkownika.
Dlatego polecam ZMIEŃ ROZMIAR
Poniżej znajduje się przykładowy kod
źródło
Jeśli android: largeHeap = „true” nie działał dla ciebie
1:
2:
Nie usuwaj Androida: largeHeap = "true"!
źródło
Użyj biblioteki ładowania obrazu, takiej jak Picasso lub Glide . Korzystanie z tych bibliotek zapobiegnie awariom w przyszłości.
źródło