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.


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.


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.


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);

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.


@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.


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 ... !!


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


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.


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 :-(


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);
           }

0

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

Dodaj te wiersze do tagu aplikacji Manifest

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

    

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.