首页 > 解决方案 > 致命异常:android.view.InflateException 由 java.lang.ClassNotFoundException 引起

问题描述

在启用了 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 文件:

<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其中确定阴影深度,并且不会创建某种构建异常。也可以正常工作,我已经测试过很多次了。

任何版本的模拟器或我拥有的具有 API 19、23、28 和 29 的 4 台设备都不会发生异常。但它在 Crashlytics 上经常被报道,所以我不确定这里的问题是什么。

该项目也使用MultiDex和调用MultiDex.install(this);项目级应用程序文件。

在构建 APK 之后,我还对其进行了分析,并且我已经看到该类存在具有用于布局膨胀的正确前导包。我还检查了 layout.xml 文件,它也有正确的包和类。此外,在 apk 中,有 3 个 dex 文件,名为classes.dex, classes2.dex, classes3.dex.

有解决方案吗?或者我应该忽略异常并继续前进,因为它不会在本地发生,或者可以说它们是特定于设备的,即使我不这么认为?

任何帮助表示赞赏,谢谢。

标签: androidlayout-inflaterinflate-exception

解决方案


  1. 确保在定义的位置有 CustomImageView 类。
  2. 如果您可以在没有 pro Guard 的情况下运行它,则可以编辑您的 pro Guard 规则以保留该文件。

    -keep class com.example.android.views.** { *; }


推荐阅读