Tôi đã làm việc trên một ứng dụng có chứa một số đồ họa vector. Gần đây tôi bắt đầu thử nghiệm nó trên Nougat và thấy nó bị rơi ngay lập tức. Logcat hiển thị Tài nguyên $ NotFoundException trong khi tải một vectơ gợi nhớ tất cả các lỗi AppCompat trong các phiên bản trước của Android với đồ họa vector. Tuy nhiên, nó chạy tốt trên KitKat, Lollipop, và Marshmallow. Nó chỉ là trên Nougat mà tôi nhận được lỗi này.
Tôi đã thu hẹp nó xuống một số lượng tệp vector nhất định gây ra ngoại lệ, nhưng tôi không thể thấy lý do tại sao chúng khác với những người khác tôi đang sử dụng. Tất cả đều được tạo từ SVG khá đơn giản từ: http://inloop.github.io/svg2android/
Tôi đoán là có điều gì đó đã thay đổi theo cách họ tạo drawables từ vectơ và vì lý do nào đó các tệp này hiện đang gây ra lỗi sao cho không thể tạo được. Khi thư viện được đưa vào drawable trên màn hình nó không thể "tìm thấy" các drawable mất tích bởi vì nó đã không được tạo ra. Tôi không chắc chắn những gì kiểm tra thêm/hạn chế là trên tập tin vector trong Nougat.
Có ai khác có kinh nghiệm này không? Bất kỳ ý tưởng tại sao? Điều gì đã thay đổi với việc xử lý vectơ của Nougat?
Sau khi trải qua những lỗi và tìm kiếm thông qua các lỗi Vector khác, tôi cập nhật cài đặt gradle tôi để:
- buildToolsVersion '25 .0.3'
- vectorDrawables.useSupportLibrary = true
- biên dịch 'com.android .Hỗ trợ: appcompat-v7: 25.4.0'
- biên dịch 'com.android.support:preference-v14:25.4.0'
- biên dịch 'com.android.support:recyclerview-v7:25.4.0'
- biên dịch 'com.android.support:design:25.4.0'
Tôi cũng đã đưa vào lớp chính:
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Các logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.MyApp.Application.MyAppApplication, PID: 4957
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.MyApp.Application.MyAppApplication/com.MyApp.Application.MyAppApplication.MyApp}: android.content.res.Resources$NotFoundException: Drawable com.MyApp.Application.MyAppApplication:drawable/icon_month with resource ID #0x7f0800da
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.content.res.Resources$NotFoundException: Drawable com.MyApp.Application.MyAppApplication:drawable/icon_month with resource ID #0x7f0800da
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/icon_month.xml from drawable resource ID #0x7f0800da
at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:725)
at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:571)
at android.content.res.Resources.getDrawable(Resources.java:767)
at android.content.Context.getDrawable(Context.java:525)
at android.support.v4.content.ContextCompatApi21.getDrawable(ContextCompatApi21.java:30)
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:372)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:202)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:190)
at android.support.v7.content.res.AppCompatResources.getDrawable(AppCompatResources.java:100)
at android.support.v7.widget.AppCompatImageHelper.setImageResource(AppCompatImageHelper.java:85)
at android.support.v7.widget.AppCompatImageView.setImageResource(AppCompatImageView.java:92)
at com.MyApp.Application.MyAppApplication.MyApp.onCreate(MyApp.java:233)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.IllegalArgumentException: Path string cannot be empty.
at android.util.PathParser.nCreatePathDataFromString(Native Method)
at android.util.PathParser.-wrap1(PathParser.java)
at android.util.PathParser$PathData.<init>(PathParser.java:74)
at android.graphics.drawable.VectorDrawable$VFullPath.updateStateFromTypedArray(VectorDrawable.java:1556)
at android.graphics.drawable.VectorDrawable$VFullPath.inflate(VectorDrawable.java:1507)
at android.graphics.drawable.VectorDrawable.inflateChildElements(VectorDrawable.java:693)
at android.graphics.drawable.VectorDrawable.inflate(VectorDrawable.java:598)
at android.graphics.drawable.DrawableInflater.inflateFromXml(DrawableInflater.java:130)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:1224)
at android.graphics.drawable.Drawable.createFromXml(Drawable.java:1197)
E/AndroidRuntime: at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:715)
... 23 more
Sự khởi đầu của tệp vectơ XML (không thể đăng toàn bộ tệp):
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="100.000000dp"
android:height="75.666667dp"
android:viewportWidth="100.000000"
android:viewportHeight="75.666667">
<group
android:translateY="75.666667"
android:scaleX="0.003333"
android:scaleY="-0.003333">
<path
android:fillColor="#000000"
android:strokeWidth="1"
android:pathData="M28898 22695 c-7 -7 -376 -19 -491 -16 -69 2 -113 -1 -122 -9 -14 -12 -296 -34
-330 -26 -18 4 -170 7 -235 4 -14 0 -47 3 -75 7 -61 9 -223 9 -265 0 -19 -4 -36 -2
-46 6 -12 10 -20 9 -39 -1 -20 -11 -35 -11 -77 -1 -38 9 -151 11 -404 8 -192 -2
-354 -6 -360 -9 -5 -3 -103 -4 -217 -3 -115 1 -210 -2 -213 -7 -3 -5 -18 -6 -34 -3
-23 5 -126 7 -310 5 -14 -1 -185 -1 -380 -1 -280 0 -567 -3 -705 -8 -5 -1 -35 1
-65 3 -100 8 -183 7 -324 -2 -77 -5 -148 -7 -158 -4 -10 2 -18 -1 -18 -7 0 -14 -35
-14 -76 1 -25 9 -39 9 -56 0 -13 -6 -81 -14 -153 -17 -71 -3 -195 -9 -275 -14 -80
-5 -152 -10 -160 -10 -138 -6 -171 -10 -184 -24 -9 -9 -16 -20 -16 -26 0 -6 -4 -11
-10 -11 -15 0 -12 21 7 42 16 18 14 19 -68 19 -121 0 -114 0 -234 -5 -113 -6 -236
-11 -550 -22 -221 -8 -229 -9 -243 -18 -7 -4 -80 -7 -162 -8 -85 0 -153 -4 -156 -9
-4 -6 -10 -6 -18 0 -6 5 -68 11 -136 11 -114 1 -181 -1 -371 -14 -36 -3
....
Cảm ơn!
Chỉnh sửa Có vẻ như vấn đề là tệp vectơ có mục nhập "pathData" dài hơn (Số đường dẫn dường như không phải là vấn đề). Lỗi này dường như xảy ra khi hàm JNI gốc GetStringUTFChars được gọi trên một mục nhập đường dẫn dài hơn và nó trả về một chuỗi rỗng mà trình phân tích cú pháp không thể vẽ. Tôi không biết nếu điều này chỉ là một điều chiều dài cũng không phải lý do tại sao điều này hoạt động tốt trong các thư viện AppCompat.
Cách giải quyết hiện tại là 1) để sử dụng bitmap cho bất kỳ vectơ nào có đường dẫn dài hoặc 2) để sửa đổi tệp xml và chia đường dẫn thành nhiều đường dẫn (Cảm ơn Lewis McGreary cho đề xuất!).
Cả hai đều yêu cầu thử nghiệm mọi đồ họa véc tơ để xác định tác phẩm nào và sau đó sửa đổi riêng các bản vẽ. Điều này không lý tưởng, đặc biệt là đối với ứng dụng cụ thể này, chọn hình ảnh từ một hồ bơi lớn.Di chuyển toàn bộ để pngs là một lựa chọn, nhưng kết quả trong một gói ứng dụng lớn hơn và rộng nghèo :(
nguồn Android liên quan đến vụ tai nạn:
PathParser JNI - here is the call to GetStringUTFChars
PathParser JNI Hwui - here is where the crash happens
Tôi không biết những gì là nguyên nhân thực tế là ở đây, nhưng tôi có thể nói rằng khi sử dụng thư viện hỗ trợ - Nougat (API 24) và trở lên nó đại biểu cho phiên bản khung công tác của VectorDrawable và cho API 23 xuống dưới, nó sử dụng phiên bản thư viện hỗ trợ. –
Điều này giúp ích. Đào sâu hơn và có vẻ như 24 cuộn Api trên các chuỗi pathData dài hơn, cho lỗi "Chuỗi đường dẫn không thể trống" ở trên. Tôi đã không thể tìm thấy nguồn tương ứng để hiển thị véc-tơ. Điều này đúng với đồ họa vector được tạo trong Android Studio bằng cách sử dụng Vector Studio tích hợp. Tôi đã tạo ra một Nougat mới, không có thư viện hỗ trợ, dự án với cùng một kết quả. Rõ ràng, thư viện hỗ trợ đang làm một công việc tốt hơn để kết xuất vectơ với dữ liệu đường dẫn dài nhưng phải làm gì một cách pratically? Kiểm tra tất cả các vectơ trên kẹo hạnh phúc? Tôi có thể ép Nougat sử dụng lib hỗ trợ không? – Emilie
Tôi không chắc chắn liệu bạn có thể bắt buộc sử dụng lib hỗ trợ không. Nếu pathData dài hơn là vấn đề và tùy thuộc vào hình ảnh cụ thể, việc tách một đường dẫn thành nhiều phần tử ngắn hơn ' 'có thể là một giải pháp. Vì vậy, đặc biệt nếu hình ảnh có nhiều thành phần trong một đường dẫn, một phần lệnh 'M' sẽ là một nơi tốt để cắt/dán vào một đường dẫn mới. –