【问题标题】:android.view.InflateException when using selectableItemBackgroundandroid.view.InflateException 使用 selectableItemBackground 时
【发布时间】:2015-10-29 08:32:02
【问题描述】:

当我的布局膨胀时,我得到了这个异常:

E AndroidRuntime: android.view.InflateException: Binary XML file line #11: Binary XML file line #11: Error inflating class <unknown>
E AndroidRuntime:        at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
E AndroidRuntime:        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
E AndroidRuntime:        at com.myapp.view.MyRecyclerAdapter.onCreateViewHolder(MyRecyclerAdapter:80)
E AndroidRuntime:        at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:5288)
E AndroidRuntime:        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4551)
E AndroidRuntime:        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4461)
E AndroidRuntime:        at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1962)

日志中没有“Caused by”,但是我添加了代码来捕获异常并调用getCause()直到它返回null,这是事件的顺序:

android.view.InflateException: Binary XML file line #11: Binary XML file line #11: Error inflating class <unknown>
android.view.InflateException: Binary XML file line #11: Error inflating class <unknown>
Error: Binary XML file line #11: Error inflating class <unknown>
android.content.res.Resources$NotFoundException: File res/drawable-v11/selectable_list_background.xml from drawable resource ID #0x7f020096
java.lang.UnsupportedOperationException: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f0100f9 a=-1}

0x7f020096 是 selectable_list_background(见下文),它引用的 TypedValue 是 ?selectableItemBackground

我将例外情况缩小到使用?selectableItemBackground。更具体地说,我使用的是 CardView:

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="@drawable/selectable_list_background"
    card_view:cardCornerRadius="4dp"
    card_view:cardElevation="4dp"
    >

这是drawable/selectable_list_background的相关部分:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="?selectableItemBackground" />
</selector>

此活动使用我自己的主题,其父主题是Theme.AppCompat.Light.NoActionBar

这段代码以前可以工作,但几个月后我才挖出这段代码,现在它崩溃并出现异常。我的猜测是这与将支持库升级到 23.0.1 并将目标 SDK 升级到 23 有关,但我还没有切换回 22 来验证这一点。

如果我删除引用?selectableItemBackground 的一行,一切正常。我也尝试了?attr/selectableItemBackground?android:attr/selectableItemBackground,但得到了相同的结果。 (后者让我相信支持库可能不是问题)。

编辑:

我在调试器里看了,怀疑是android.content.res.Resources里面loadDrawable()里面的这段代码:

Drawable loadDrawable(TypedValue value, int id, Theme theme) throws NotFoundException {
    [...]
    dr = loadDrawableForCookie(value, id, null);

注意这个函数带了一个主题,但是在调用loadDrawableForCookie()的时候并没有传入,也就是最终触发第一个异常的方法:

java.lang.UnsupportedOperationException: Failed to resolve attribute at index 0: TypedValue{t=0x2/d=0x7f0100f9 a=-1}
    at android.content.res.TypedArray.getDrawable(TypedArray.java:867)
    at android.graphics.drawable.StateListDrawable.inflateChildElements(StateListDrawable.java:170)
    at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:115)
    at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:1215)
    at android.graphics.drawable.Drawable.createFromXml(Drawable.java:1124)
    at android.content.res.Resources.loadDrawableForCookie(Resources.java:2630)
    at android.content.res.Resources.loadDrawable(Resources.java:2540)
    at android.content.res.TypedArray.getDrawable(TypedArray.java:870)
    at android.view.View.<init>(View.java:4280)

这段代码似乎是 Android 6.0 的新代码——5.0 的代码有很大的不同,但是加载 drawable 时传入了主题。并且主题是必需的 AFAICT - 有问题的属性是 AppCompat 的一部分,因此它需要活动的主题来解决它。

不过,这似乎是一个明显的错误,所以我不相信我在这里是在正确的轨道上。有什么想法吗?

【问题讨论】:

  • AppTheme 使用的父主题是哪个?
  • @FabinPaul 对不起,我应该提到这一点。父主题是Theme.AppCompat.Light.NoActionBar
  • 您是否尝试过使用父主题Base.V7.Theme.AppCompat.Light
  • 试过了(当然要调整windowActionBarwindowNoTitle),但是在膨胀时有同样的异常,具有相同的堆栈跟踪。
  • “我的猜测是这与将支持库升级到 23.0.1 并将目标 SDK 升级到 23 有关,但我还没有切换回 22 来验证这一点。”你是对的,我遇到了同样的问题,需要再次切换到版本 22。 (stackoverflow.com/questions/37376766/…)

标签: android android-layout android-view android-attributes


【解决方案1】:

正如@Artjom 所说,问题在于在创建自定义视图时传递application context。我也面临同样的问题,我通过getApplicationContext() 而不是activity 作为context。将Activity 作为context 传递后,问题已解决。

希望对其他人有所帮助。

【讨论】:

    【解决方案2】:

    官方答案 - 您不能将主题属性用于 android:drawableandroid:src 属性。根本不可能,设计使然。还有另一个答案探讨了相同的问题并提供了解决方案:How to reference style attributes from a drawable?

    在我的情况下,我真的不能这样做,因为 AppCompat 的 ?selectableItemBackground 引用了一个私有可绘制对象。所以我选择了代码解决方案 - 我将前景设置为 ?selectableItemBackground 而未选择卡片,并在我处于选择模式时设置为我自己的可绘制状态列表。

    这是一个非常丑陋的解决方案,如此丑陋,以至于我不打算在这里分享代码,但到目前为止我能想到的最好的解决方案。如果有人有更好的解决方案,我很乐意听到。

    【讨论】:

    • 您确定吗,您使用 Activity 作为充气的 Context 而不是 ApplicationContext
    • 谢谢!错误的上下文也可能是失败的原因
    • @ArtjomKönig 你拯救了我的一天。
    【解决方案3】:

    不幸的是,其他答案不是我的情况。为我工作的方法是检查您的活动是否使用 AppCompat 主题样式:

        <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <!-- Customize your theme here. -->
        </style>
    

    然后在你的活动中使用 AppCompat 主题(在很多方面,但我展示了使用 Manifest 的方式):

    <application
            android:name=".Abbott"
            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">
    
        <!-- Any configuration inside -->
    
    </application>
    

    【讨论】:

      【解决方案4】:

      我在使用 androidx 片段测试组件时遇到了同样的错误。默认launchFragmentInContainer()使用主题FragmentScenarioEmptyFragmentActivityTheme,导致报错。

      简单的解决方法是使用您自己的扩展 AppCompat 的主题:

      launchFragmentInContainer(theme = R.style.AppTheme)

      【讨论】:

      • 这正是我一直在寻找的上下文,而且效果很好!谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-04
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      相关资源
      最近更新 更多