В сборке релиза с включенным proguard есть исключение, которое я не понял, почему это происходит, это также не воспроизводится локально. Конфигурации должны быть выполнены правильно, так как я поставил их в нижней части вопроса после исключения.
Исключение составляет:
Fatal Exception: android.view.InflateException: Binary XML file line #28: Binary XML file line #28: Error inflating class com.example.android.views.CustomImageView
Caused by java.lang.ClassNotFoundException: Didn't find class "com.example.android.views.CustomImageView" on path: DexPathList[[zip file "/data/app/com.example.android-ZRve1QYwB0aaNC0difXwrA==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.android-ZRve1QYwB0aaNC0difXwrA==/lib/arm64, /system/lib64, /vendor/lib64, /product/lib64]]
at dalvik.system.BaseDexClassLoader.findClass + 93(BaseDexClassLoader.java:93)
at java.lang.ClassLoader.loadClass + 379(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass + 312(ClassLoader.java:312)
at android.view.LayoutInflater.createView + 613(LayoutInflater.java:613)
at android.view.LayoutInflater.createViewFromTag + 801(LayoutInflater.java:801)
at android.view.LayoutInflater.createViewFromTag + 741(LayoutInflater.java:741)
at android.view.LayoutInflater.rInflate + 874(LayoutInflater.java:874)
at android.view.LayoutInflater.rInflateChildren + 835(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflate + 877(LayoutInflater.java:877)
at android.view.LayoutInflater.rInflateChildren + 835(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflate + 877(LayoutInflater.java:877)
at android.view.LayoutInflater.rInflateChildren + 835(LayoutInflater.java:835)
at android.view.LayoutInflater.inflate + 515(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate + 423(LayoutInflater.java:423)
at com.example.android.fragments.MyFragment.onCreateView + 160(MyFragment.java:160)
at androidx.fragment.app.Fragment.performCreateView + 2600(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState + 881(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState + 1238(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState + 1303(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps + 439(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps + 2079(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether + 1869(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute + 1824(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions + 1727(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run + 150(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback + 808(Handler.java:808)
at android.os.Handler.dispatchMessage + 101(Handler.java:101)
at android.os.Looper.loop + 166(Looper.java:166)
at android.app.ActivityThread.main + 7529(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run + 245(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main + 921(ZygoteInit.java:921)
Связано XML file:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.android.views.CustomImageView
android:id="@+id/iconImageView"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:contentDescription="icon"
app:compatElevation="10dp"
tools:ignore="HardcodedText" />
<!-- rest of the layout, not important -->
</RelativeLayout>
Добавлено правило proguard, и я даже добавил аннотацию @Keep
, чтобы сказать proguard исключительно не запутывать пакет вызывающего абонента и класс всем, что у него есть.
-keep class com.example.android.views.** { *; }
package com.example.android.views;
import androidx.annotation.Keep;
@Keep
public class CustomImageView extends AppCompatImageView
{
// rest of the code
}
Если это помогает, представление используется во фрагменте и использует Renderscript для создания пользовательских теней в зависимости от источника изображения, которое у него есть. Атрибут compatElevation
определен в attrs.xml
, который определяет глубину тени и не создает каких-либо исключений при сборке. Также работает правильно, я проверял это несколько раз.
Исключение не происходит ни на одной версии эмуляторов или на 4 устройствах с API 19, 23, 28 и 29, которые у меня есть. Но об этом довольно часто сообщают в Crashlytics, поэтому я не уверен, в чем здесь проблема.
Проект использует MultiDex
и также вызывает MultiDex.install(this);
для файла приложения уровня проекта.
Я также проанализировал APK после сборки и увидел, что класс существует с правильным ведущим пакетом для разметки макета. Я также проверил файл макета. xml, и он также имеет правильный пакет и класс. Также в apk есть 3 файла dex с именем classes.dex, classes2.dex, classes3.dex
.
Есть ли решение для этого? Или я должен игнорировать исключение и двигаться дальше, потому что это не происходит локально, или я могу сказать, что они определяются устройством c, хотя я так не думаю?
Любая помощь приветствуется, спасибо.