Android Canvas: rysowanie zbyt dużej mapy bitowej

87

Używam Ubuntu 16.04. A na Android Studio, gdy próbuję uruchomić moją aplikację w emulatorze, pojawia się następujący błąd:

KRYTYCZNY WYJĄTEK: główny proces: tutaj nazwa projektu, PID: 2528 java.lang.RuntimeException: Canvas: próba narysowania zbyt dużej (216090000 bajtów) mapy bitowej. na android.view.DisplayListCanvas.throwIfCannotDraw (DisplayListCanvas.java:260) na android.graphics.Canvas.drawBitmap (Canvas.java:1415) na android.graphics.drawable.BitmapDrawable.draw (BitmapDrawable.java:528) na android. widget.ImageView.onDraw (ImageView.java:1316) pod adresem android.view.View.draw (View.java:17185) pod adresem android.view.View.updateDisplayListIfDirty (View.java:16167) pod adresem android.view.View.draw (View.java:16951) na android.view.ViewGroup.drawChild (ViewGroup.java:3727) na android.view.ViewGroup.dispatchDraw (ViewGroup.java:
itp...

Musiałem jednak przejść przez kilka kółek, aby mój emulator działał, jednak potrzebowałem utworzyć łącze symboliczne, aby móc uruchomić emulator na AMD. Nie jestem pewien, czy to jest częścią problemu. I za moje życie nie mogę zrozumieć, dlaczego nadal to robi. W mojej grupie są inni, którzy dobrze emulują projekt na tym samym emulowanym telefonie i SDK.

Francisco
źródło
czy próbowałeś czytać bitmapę w mniejszym rozmiarze używając BitmapOption.inSampleSize?
L. Swifter
1
wypróbuj swoją mapę bitową, korzystając z tego developer.android.com/training/displaying-bitmaps/ ...
Nishant Verma
10
W moim przypadku rozwiązaniem było przeniesienie (hi-res) splash bitmap z drawable do drawable-xxhdpi. Miałem ten sam problem. Nie podejrzewałem, że problem stanowi mój ekran powitalny, ponieważ jest on wyświetlany po uruchomieniu aplikacji, ale okazało się, że problem stanowi ekran powitalny. Ekran powitalny w moim przypadku ma rozdzielczość xxhdpi i został omyłkowo umieszczony w folderze do rysowania, zamiast do drawable-xxhdpi. To sprawiło, że Android założył, że ekran powitalny ma rozdzielczość mdpi i skaluje obraz do 3 * 3 razy większy od wymaganego rozmiaru i próbuje utworzyć bitmapę.
Zubair Rehman
Czy dzieje się to tylko na emulatorze czy też na urządzeniu z takim samym rozmiarem ekranu?
Dmitry

Odpowiedzi:

200

Przenieś swój obraz w (hi-res) drawable do drawable-xxhdpi . Ale podczas tworzenia aplikacji nie musisz używać dużego obrazu. Zwiększy to rozmiar pliku APK.

Md Imran Choudhury
źródło
6
Dzięki, to też działało, gdy mój obraz miał tylko 500 kb, ale rozdzielczość była zdecydowanie za wysoka.
ashishdhiman 2007
1
Otrzymuję ten błąd podczas ładowania obrazów z interfejsu API. Jakie mogłoby być rozwiązanie w takim przypadku?
Rohit Singh
2
Napotkałem ten sam problem w Firebase Crashlytics, ale nie wspomina o dokładnym pliku + kodzie linii, więc nie wiem, jaki jest dokładny obraz, który powoduje tę awarię. Oczywiście w moim pliku res jest dużo zdjęć, jak mogę zlokalizować problematyczny
ravid rinek
15

Rozwiązaniem jest przeniesienie obrazu z drawable/folderu do drawable-xxhdpi/folderu, o czym wspominali również inni.

Ale ważne jest również, aby zrozumieć, dlaczego ta nieco dziwna sugestia w rzeczywistości pomaga:

Powodem jest to, że drawable/folder istnieje we wczesnych wersjach Androida i jest odpowiednikiem drawable-mdpi. Gdy obraz, który znajduje się tylko w drawable/folderze, jest używany na xxhdpiurządzeniu, potencjalnie już duży obraz jest przeskalowywany 3-krotnie, co w niektórych przypadkach może spowodować eksplozję pamięci obrazu.

Nace
źródło
2
Czy to oznacza, że ​​mogę usunąć drawable/katalog, jeśli mam zasób w innych drawable-xkatalogach?
Karl Taylor
14

Miałem ten sam problem. Jeśli spróbujesz przesłać obraz, który jest zbyt duży na niektórych urządzeniach o niskiej rozdzielczości, aplikacja zwinie się. Możesz utworzyć kilka obrazów o różnych rozmiarach (hdpi, xxdpi i więcej) lub po prostu użyć zewnętrznej biblioteki do załadowania obrazów, które szybko i skutecznie rozwiązują problem. Użyłem biblioteki Glide (możesz użyć innej biblioteki, takiej jak Picasso).

    panel_IMG_back = (ImageView) findViewById(R.id.panel_IMG_back);
    Glide
            .with(this)
            .load(MyViewUtils.getImage(R.drawable.wallpaper)
            .into(panel_IMG_back);
Guy4444
źródło
6

Okazuje się, że problemem był główny obraz, którego używaliśmy w tym czasie w naszej aplikacji. Rzeczywisty rozmiar obrazu był za duży, więc skompresowaliśmy go. Potem działało jak urok, bez utraty jakości, a aplikacja działała dobrze na emulatorze.

Francisco
źródło
@BekaBot Oryginalne pytanie było od jakiegoś czasu. Ale jeśli dobrze pamiętam, po prostu uruchomiliśmy nasz obraz przez kompresor obrazu online, a następnie ponownie uruchomiliśmy naszą aplikację i wszystko działało dobrze. Mam nadzieję, że to pomoże.
Francisco
3

Miałem również ten problem, gdy próbowałem dodać ekran powitalny do aplikacji na Androida za pośrednictwem pliku launch_backgrgound.xml. problemem było rozwiązanie. była zbyt wysoka, więc ślad pamięci obrazów eksplodował i spowodował awarię aplikacji, stąd przyczyna tego błędu. więc po prostu zmień rozmiar obrazu za pomocą witryny o nazwie Nativescript Image Builder, więc mam ldpi, mdpi i całą resztę i działało dobrze.

williamjnrkdd
źródło
zachowaj mój dzień, ten sam problem.
Abdul Basit Rishi
2

Ponieważ ten błąd był taki, jak inni powiedzieli duży obraz (1800px X 900px), który był w katalogu do rysowania, zredagowałem obraz i zmniejszyłem rozmiar proporcjonalnie za pomocą Photoshopa i zadziałało ... !!

Ishimwe Aubain Consolateur
źródło
2

jeśli używasz Picassa, zmień na Glide w ten sposób.

Usuń Picasso

Picasso.get().load(Uri.parse("url")).into(imageView)

Zmień Glide

Glide.with(context).load("url").into(imageView)

Bardziej wydajne Glide niż Picasso rysuje do dużych bitmap

Deniz
źródło
3
Otrzymałem ten sam błąd w Glide, ładowanie obrazu przez URL i to tylko 2 MB obrazu.
Prince Dholakiya
1

Właśnie utworzyłem katalog drawable-xhdpi (możesz go zmienić zgodnie z potrzebami) i skopiowałem wklejone wszystkie obrazy do tego katalogu.

Sourabh Chaudhary
źródło
0

W moim przypadku musiałem usunąć platformę Android i dodać ją ponownie. Coś utknęło i skopiowanie całego mojego kodu do innej aplikacji działało jak urok - stąd mój pomysł na wyczyszczenie kompilacji dla Androida poprzez usunięcie platformy.

cordova platform remove android
cordova platform add android

Myślę, że to jakiś porządek, który musisz zrobić od czasu do czasu :-(

pieroksy
źródło
0

Może to być problem z Glide. Użyj tego, gdy próbujesz załadować wiele obrazów, a niektóre z nich są bardzo duże:

Glide.load("your image path")
                       .transform(
                               new MultiTransformation<>(
                                       new CenterCrop(),
                                       new RoundedCorners(
                                               holder.imgCompanyLogo.getResources()
                                                       .getDimensionPixelSize(R.dimen._2sdp)
                                       )
                               )
                       )
                       .error(R.drawable.ic_nfs_default)
                       .into(holder.imgCompanyLogo);
           }
Deepak Rajput
źródło
0

To rozwiązanie zadziałało dla mnie.

Dodaj te wiersze do tagu aplikacji Manifest

android:largeHeap="true"
android:hardwareAccelerated="false"

    
Abdul Basit Rishi
źródło