“Canvas: cố gắng vẽ bitmap quá lớn” khi Kích thước hiển thị Android N được đặt lớn hơn Nhỏ


81

Tôi có một ứng dụng đã xuất bản bị lỗi khi khởi động trên Android N khi Display sizecài đặt hệ điều hành mới được giới thiệu được đặt thành giá trị quá lớn.

Khi tôi nhìn vào logcat, tôi thấy thông báo sau:

java.lang.RuntimeException: Canvas: trying to draw too large(106,975,232 bytes) bitmap.

Tôi đã tìm ra vấn đề với ImageView trong Hoạt động đầu tiên của mình, nó hiển thị một hình nền lớn đẹp mắt. Hình ảnh được đề cập là 2048x1066 và nằm trong drawablesthư mục chung của tôi , vì vậy bất kể mật độ, hình ảnh này sẽ được sử dụng.

Mọi thứ hoạt động ổn khi Display sizecài đặt Small. Nhưng khi tôi đi lên Default, nó ngừng hoạt động. Nếu sau đó tôi hoán đổi hình ảnh với một hình ảnh nhỏ hơn, nó hoạt động tại Default, nhưng nếu tôi chuyển lên Large, nó lại ngừng hoạt động.

Tôi đoán rằng việc điều chỉnh Display sizelên khiến thiết bị của bạn hoạt động giống như một thiết bị vật lý nhỏ hơn với mật độ điểm ảnh cao hơn. Nhưng tôi không hiểu mình phải làm gì ở đây. Nếu tôi đặt các hình ảnh nhỏ dần dần để có độ phân giải cao hơn dần dần, nó sẽ không đẹp trên các màn hình thực sự lớn. Hay tôi không hiểu điều gì đó?

Bât cư thông tin được cung câp nao cung được la sự suât hiện tuyệt vơi.


23
"Hình ảnh được đề cập là 2048x1066 và nằm trong thư mục có thể vẽ chung của tôi, vì vậy bất kể mật độ, hình ảnh này sẽ được sử dụng" - res/drawable/là một từ đồng nghĩa với res/drawable-mdpi/. Nếu bạn muốn hình ảnh không bị thay đổi tỷ lệ dựa trên mật độ, hãy sử dụng res/drawable-nodpi/hoặcres/drawable-anydpi/ .
CommonsWare

3
"Bạn đang nói rằng một hình ảnh 100x100 pixel sống trong nhiều thư mục tài nguyên khác nhau thực sự được chia tỷ lệ để tạo ra một phiên bản ảo có độ phân giải khác trước khi chuyển sang bố cục?" - điều đó phụ thuộc vào mật độ bạn có và thiết bị bạn đang chạy. Nếu có kết quả khớp chính xác, không có gì được lấy mẫu lại. Nếu không có kết quả khớp chính xác, hình ảnh của mật độ lân cận sẽ được lấy mẫu lại. Vì vậy, nếu bạn chỉ có res/drawable/foo.png(hay còn gọi là, res/drawable-mdpi/foo.png) và thiết bị của bạn cũng vậy xhdpi, hình ảnh sẽ được nhân đôi dọc theo cả hai trục, chiếm 4 lần bộ nhớ.
CommonsWare

4
Giá trị 106975232 trong lỗi của bạn xảy ra là chính xác 49 lần độ phân giải hình ảnh, ngụ ý lấy mẫu lại 7 lần dọc theo cả hai trục. Đó là cao hơn rất nhiều so với tôi mong đợi. Tôi đã không nhận được một cơ hội chưa chơi xung quanh với các thiết lập kích thước hiển thị trong Android 7.0, vì vậy tôi sẽ nói thêm rằng để tôi ngày càng phát triển to-do list ...
CommonsWare

6
Bắt đẹp trên 49x! Tôi nghĩ tôi có thể giải thích tại sao nó lại cao như vậy. Hãy nhớ rằng số đó là byte. Hình ảnh này là 24 bit, nhưng nó có thể được đọc ở 32 bit trên mỗi pixel. Điều đó sẽ làm cho nó có 8732672 byte trong bộ nhớ, tương đương với con số đó chính xác là 12,25 lần, điều này ngụ ý tỷ lệ 3,5 lần dọc theo mỗi trục. Thiết bị này là xxhdpi, vì vậy có vẻ như nó có thể đúng. Dù bằng cách nào, tôi không biết các tài nguyên sẽ được lấy mẫu lại như vậy. Cảm ơn bạn vì sự giúp đỡ! (Bằng cách này, di chuyển các hình ảnh để drawable-nodpi không thực sự sửa chữa nó.)
Brian Rak

1
Bạn thực sự nên chấp nhận câu trả lời của johan
S. Jacob Powell

Câu trả lời:


166

Tôi trong trường hợp của tôi, chuyển bitmap giật gân (độ phân giải cao) từ drawable sang drawable-xxhdpi là giải pháp.

Tôi đã từng gặp vấn đề tương tự. Tôi không nghi ngờ màn hình giật gân của mình là vấn đề, vì nó được hiển thị khi ứng dụng được khởi động, nhưng hóa ra màn hình giật gân mới là vấn đề.

Màn hình giật gân trong trường hợp của tôi có độ phân giải xxhdpi và nó đã bị đặt nhầm vào thư mục có thể vẽ , thay vì có thể vẽ-xxhdpi . Điều này khiến Android cho rằng màn hình giật gân có độ phân giải mdpi và chia tỷ lệ hình ảnh thành 3 * 3 lần kích thước yêu cầu và cố gắng tạo một bitmap.


Tôi đoán: vậy, chẳng hạn như android chia tỷ lệ hình ảnh từ xxhdpi sang hdpi để thành hình ảnh nhẹ hơn? như bạn nói từ 3 * 3 -> 1/1 đến 1/3 chẳng hạn?
Ninja Coding

Như kalsara Magamage lưu ý, đây bây giờ là mipmap-xxhdpi.
Dana Robinson

36

Tôi đã giải quyết được sự cố sau khi thêm mã bên dưới vào thẻ ứng dụng của tệp Manifest ở giữa các dòng android:.

android:hardwareAccelerated="false"

3
Chà, sau vài giờ, giải pháp này có hiệu quả đối với các sự cố di động của xiaomi và Samsung.
Shihab Uddin

3
Điều này sẽ dẫn đến việc vô hiệu hóa tất cả các độ cao của CardView. Vì vậy, giải pháp thích hợp sẽ là chia tỷ lệ bitmap thành kích thước nhỏ hơn.
Sachin Soma

Thay vì vô hiệu hóa tăng tốc phần cứng ở cấp Ứng dụng, điều khiển nó ở cấp Hoạt động, Cửa sổ, Chế độ xem sẽ hữu ích hơn.
Mukhammadsher

Tuy nhiên, có một số vấn đề khác được nêu ra sau khi thực hiện android:hardwareAccelerated="false" . hiển thị chế độ xem kỳ lạ trong một số thiết bị có cấp API dưới 22.
Hoàng tử Dholakiya

Đừng làm vậy, nó làm chậm ứng dụng của bạn.
Curio

11

Tôi không biết nó có giúp được gì không, nhưng tôi sẽ để nó ở đây. Trong trường hợp của tôi - vấn đề chỉ xảy ra trên các thiết bị Sumsung chạy Android 7 và vấn đề nằm ở tỷ lệ màn hình giật gân. sau khi thay đổi chiều cao thành 1024 px - mọi thứ hoạt động tốt


Vấn đề của tôi là bitmap (jpg, png) trong thư mục có thể vẽ (không có hậu tố). Đó là sự ngu ngốc của tôi, nhưng có lẽ nó sẽ giúp ai đó :-)
gingo

Điều này là hữu ích! Vấn đề tương tự chỉ có Samsung ... Bạn đã gặp phải vấn đề gì đầu tiên và Bạn đã khắc phục nó như thế nào?
M'hamed

Có phải bạn đang cố tải hình ảnh từ URL. Tôi đang gặp phải vấn đề tương tự chỉ với Samsung Galaxy S6 trên Android 7. Tôi đang tải hình ảnh trong RecyclerView. Tôi vẫn không thể tìm ra điều này. @ M'hamed
Rohit Singh

9

Di chuyển hình ảnh của bạn trong tệp có thể vẽ sang mipmap-xxhdpi. Hình ảnh của bạn ở định dạng bitmap, vì vậy bạn nên đặt hình ảnh của mình vào thư mục mipmap thì nó sẽ hoạt động


1
AFAIK thư mục mipmap chỉ dành cho các biểu tượng trình khởi chạy. Tôi chưa bao giờ sử dụng nó cho bất cứ điều gì khác. Xem stackoverflow.com/a/28065664/4034572
Albert Vila Calvo

Vâng, điều này đã làm việc cho tôi. Tôi có kích thước hình ảnh khoảng 1MB và tôi đặt chúng vào mipmap-xxhdpi


3

nếu bạn sử dụng Picasso, hãy thay đổi thành Glide như thế này.

Xóa picasso

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

Thay đổi Lướt

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

Hiệu quả hơn


Tôi vẫn gặp lỗi ngay cả khi chuyển sang Glide từ Picasso. Trên điện thoại Samsung J6. Và Moto Z2 :(
Rohit Singh

1

Có một số tình huống trong đó Bản đồ gốc cần được vẽ vào ImageViews, ứng dụng Chỉnh sửa ảnh, v.v.,

như vịnh đã đề cập ở trên cài đặt

android:hardwareAccelerated="false"

sẽ Gây ra trải nghiệm giao diện người dùng không tốt, Bạn có thể đặt phần cứng Chỉ được tăng tốc một Hoạt động được chọn trong đó hình ảnh có độ phân giải cao được vẽ

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

1

Tôi đã kiểm tra Logcat

Process: co.coolresume, PID: 11145 java.lang.RuntimeException: Canvas: cố gắng vẽ bitmap quá lớn (572166144byte). tại android.view.DisplayListCanvas.throwIfCannotDraw (DisplayListCanvas.java:229) tại android.view.RecordingCanvas.drawBitmap (RecordingCanvas.java:97) tại android.graphics.drawable.BitmapDrawable.draw (BitmapDrawable) tại android.java:529 tại android. widget.ImageView.onDraw (ImageView.java:1367) tại android.view.View.draw (View.java:19380)

Tôi đã giải quyết lỗi bằng cách sử dụng tệp kê khai tiếp theo

 <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:hardwareAccelerated="false">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

0

Các tệp biểu tượng quá lớn để Android tải một cách hiệu quả và trơn tru. Android nhận ra điều này bằng các thuật toán thông minh của nó.

Bạn có thể thay đổi kích thước các tệp biểu tượng bằng cách sử dụng Final Android Resizer bằng asystat. Thay đổi kích thước chúng thành "xhdpi" hoặc thấp hơn.

Đặt các bức ảnh đã thay đổi kích thước ở dạng có thể vẽ hoặc ghi đè lên các tệp biểu tượng lớn hiện có.

Sau đó, bạn đã hoàn tất.


0

nếu bạn đang sử dụng tính năng lướt và bạn đang tải 1k hình ảnh cùng một lúc hoặc một số hình ảnh thì đó là vấn đề khi lướt hoặc bất cứ điều gì bạn đang làm để đặt chế độ xem hình ảnh. bạn có thể giải quyết nó chỉ bằng cách áp dụng loại tỷ lệ trong lướt.



0

nó được giải quyết bằng cách thay đổi kích thước hình ảnh thành kích thước thấp hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.