javaandroidandroid-support-libraryandroid-6.0-marshmallowinflate-exception

"android.view.InflateException" being thrown on inflating RecyclerView item's layout in onCreateViewHolder method on Marshmallow(6.0+) devices


I have created an app with RecyclerView using v7:28.0.0 support libraries and app runs fine on Android 8.0+ devices when testing. But when using Android 6.0/6.0.1 devices, app crashed with:

E/AndroidRuntime: FATAL EXCEPTION: main

android.view.InflateException: Binary XML file line #38: Binary XML file line #38: Error inflating class <unknown>

Gradle file:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.toastinterceptor"
        minSdkVersion 23
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner 
"androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha05'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
    implementation 'com.google.android.material:material:1.1.0-alpha06'
    testImplementation 'junit:junit:4.13-beta-3'
    androidTestImplementation 'androidx.test:runner:1.2.0-beta01'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-beta01'

//    support dependencies
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'

//    Room dependencies
    def room_version = "2.1.0-beta01"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
    testImplementation "androidx.room:room-testing:$room_version"

//    support design dependencies
    implementation "com.android.support:design:28.0.0"
    implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
}

activity_main:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:listitem="@layout/rv_list"
    android:scrollbars="vertical"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    />

<TextView
    android:id="@+id/empty_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:visibility="gone"
    android:text="@string/nothing_to_show" />

rv_list:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/border"
android:orientation="vertical"
android:padding="5dp">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv_date"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.8"
        android:gravity="center_vertical"
        android:hint="@string/event_time"
        android:textSize="15sp" />

    <ImageView
        android:id="@+id/iv_options"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.1"
        android:contentDescription="@string/options_icon"
        android:src="@drawable/ic_garbage" />
</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="65dp"
        android:layout_height="65dp"
        android:contentDescription="@string/app_icon"
        android:src="@drawable/ic_launcher_foreground" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="@drawable/divider_horizontal"
        android:orientation="vertical"
        android:showDividers="middle"
        android:padding="5dp">

        <TextView
            android:id="@+id/tv_pkgName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/package_name"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/tv_msg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/toast_content"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:textSize="15sp" />
    </LinearLayout>
</LinearLayout>

styles:

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">true</item>
    <item name="windowNoTitle">false</item>
</style>

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

RecyclerView.Adapter class:

public class ToastListAdapter extends RecyclerView.Adapter<ToastListAdapter.ToastViewHolder> {

private Context context;
private LayoutInflater inflater;
private List<ToastEntity> toasts = Collections.emptyList();
private ToastRepository toastRepository;

ToastListAdapter(Application application) {
    this.context = application.getApplicationContext();
    inflater = LayoutInflater.from(context);
    toastRepository = new ToastRepository(application);
}

void setToasts(List<ToastEntity> toasts) {
    this.toasts = toasts;
    notifyDataSetChanged();
}


@NonNull
@Override
public ToastViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.rv_list, parent, false);
    return new ToastViewHolder(view);
}
...
...
class ToastViewHolder extends RecyclerView.ViewHolder {
    private TextView tv_date, tv_pkgName, tv_msg;
    private ImageView iv_icon, iv_options;

    ToastViewHolder(@NonNull View itemView) {
        super(itemView);
        tv_date = itemView.findViewById(R.id.tv_date);
        tv_pkgName = itemView.findViewById(R.id.tv_pkgName);
        tv_msg = itemView.findViewById(R.id.tv_msg);
        iv_options = itemView.findViewById(R.id.iv_options);
        iv_icon = itemView.findViewById(R.id.iv_icon);

    }
}
}

debug:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.toastinterceptor, PID: 7581
android.view.InflateException: Binary XML file line #38: Binary XML file line #38: Error inflating class <unknown>
    at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
    at com.example.toastinterceptor.ToastListAdapter.onCreateViewHolder(ToastListAdapter.java:46)
    at com.example.toastinterceptor.ToastListAdapter.onCreateViewHolder(ToastListAdapter.java:24)
    at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6949)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6118)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6001)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5997)
    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2227)
    at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1558)
    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1518)
    at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:613)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4032)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3749)
    at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4302)
    at android.view.View.layout(View.java:17211)
    at android.view.ViewGroup.layout(ViewGroup.java:5584)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2001)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1844)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1753)
    at android.view.View.layout(View.java:17211)
    at android.view.ViewGroup.layout(ViewGroup.java:5584)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
    at android.view.View.layout(View.java:17211)
    at android.view.ViewGroup.layout(ViewGroup.java:5584)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2001)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1844)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1753)
    at android.view.View.layout(View.java:17211)
    at android.view.ViewGroup.layout(ViewGroup.java:5584)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
    at android.view.View.layout(View.java:17211)
    at android.view.ViewGroup.layout(ViewGroup.java:5584)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2001)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1844)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1753)
    at android.view.View.layout(View.java:17211)
    at android.view.ViewGroup.layout(ViewGroup.java:5584)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
    at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2763)
    at android.view.View.layout(View.java:17211)
    at android.view.ViewGroup.layout(ViewGroup.java:5584)
    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2640)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2285)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1343)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6826)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:901)
    at android.view.Choreographer.doCallbacks(Choreographer.java:703)
    at android.view.Choreographer.doFrame(Choreographer.java:638)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:887)
    at android.os.Handler.handleCallback(Handler.java:815)
    at android.os.Handler.dispatchMessage(Handler.java:104)
    at android.os.Loope
Application terminated.

How can make the app run on Android versions starting from 6.0? Does the support library work on Android versions starting from 6.0? Can I use multiple versions of support libraries or do I have to remove components like RecyclerView altogether for lower Android versions. Please assist.


Solution

  • The error is complaining about line 38 of rv_list. That is:

    android:src="@drawable/ic_launcher_foreground"
    

    In a typical Android Studio project, ic_launcher_foreground is defined in res/drawable-v24/. This says "only use this resource on API Level 24 and higher devices". So, unless you have done something to create another version of this resource that works on older devices, you cannot inflate your layout on Android 6.0 (API Level 23) and below.

    You need that android:src attribute to point to a drawable resource that you have on all versions of Android. Or, if you plan to fill in the ImageView at runtime, remove android:src from the layout.