在 Android 开发中 , 使用 Jetpack 的 Navigation 组件报如下错误 :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: cn.zkhw.client, PID: 31489
java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.zkhw.client/cn.zkhw.client.BottomNavigationActivity}: android.view.InflateException: Binary XML file line #31 in cn.zkhw.client:layout/activity_bottom_navigation: Binary XML file line #31 in cn.zkhw.client:layout/activity_bottom_navigation: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4765)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4983)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:123)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:3059)
at android.os.Handler.dispatchMessage(Handler.java:117)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:293)
at android.app.ActivityThread.loopProcess(ActivityThread.java:9934)
at android.app.ActivityThread.main(ActivityThread.java:9923)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1240)
Caused by: android.view.InflateException: Binary XML file line #31 in cn.zkhw.client:layout/activity_bottom_navigation: Binary XML file line #31 in cn.zkhw.client:layout/activity_bottom_navigation: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #31 in cn.zkhw.client:layout/activity_bottom_navigation: Error inflating class fragment
Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class androidx.navigation.fragment.NavHostFragment that is not a Fragment
at android.app.Fragment.instantiate(Fragment.java:543)
at android.app.FragmentContainer.instantiate(FragmentContainer.java:53)
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3569)
at android.app.FragmentController.onCreateView(FragmentController.java:105)
at android.app.Activity.onCreateView(Activity.java:7693)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1083)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1011)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:975)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1137)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1098)
at android.view.LayoutInflater.inflate(LayoutInflater.java:696)
at android.view.LayoutInflater.inflate(LayoutInflater.java:540)
at com.android.internal.policy.HwPhoneLayoutInflater.inflate(HwPhoneLayoutInflater.java:138)
at cn.zkhw.client.databinding.ActivityBottomNavigationBinding.inflate(ActivityBottomNavigationBinding.java:48)
at cn.zkhw.client.databinding.ActivityBottomNavigationBinding.inflate(ActivityBottomNavigationBinding.java:42)
at cn.zkhw.client.BottomNavigationActivity.onCreate(BottomNavigationActivity.kt:21)
at android.app.Activity.performCreate(Activity.java:8592)
at android.app.Activity.performCreate(Activity.java:8565)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1344)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4733)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4983)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:123)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:3059)
at android.os.Handler.dispatchMessage(Handler.java:117)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:293)
at android.app.ActivityThread.loopProcess(ActivityThread.java:9934)
at android.app.ActivityThread.main(ActivityThread.java:9923)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1240)
核心报错信息 :
Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class androidx.navigation.fragment.NavHostFragment that is not a Fragment
Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class xx.NavHostFragment that is not a Fragment
Navigation 的常见错误 , 按照下面的步骤逐个排查 ;
使用 Navigation 需要 navigation-fragment 和 navigation-ui 依赖 , 排查这两个依赖库是否已经导入 , 使用 Java 语言 和 Kotlin 语言 导入的依赖是不同的 ,
implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.navigation:navigation-ui:2.3.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
正确的 Navigation 的 布局组件 是下面的样式的 :
<fragment
android:id="@+id/nav_host_fragment_activity_bottom_navigation"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
查看 android:name 属性设置的是否是 androidx.navigation.fragment.NavHostFragment ;
查看 app:defaultNavHost=“true” 属性是否设置 ;
查看 NavigationGraph 的设置 app:navGraph=“@navigation/mobile_navigation” 是否存在 ;
再跳转到 NavigationGraph 文件 mobile_navigation.xml 中查看 , 配置的 Fragment 是否正确 ;
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="cn.zkhw.client.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_dashboard"
android:name="cn.zkhw.client.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" />
<fragment
android:id="@+id/navigation_notifications"
android:name="cn.zkhw.client.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
</navigation>
如果 Activity 中使用了 Fragment , 当前的 Activity 必须是 FragmentActivity 或 FragmentActivity 的子类 ;
一般情况下 Activity 都是 FragmentActivity 或 AppCompatActivity ;
AppCompatActivity 是 Android 支持库 中的一个 核心类 , 它允许开发者在使用较老版本的 Android 系统时也能利用一些新版本的特性和样式 ;
Android 支持库 指的是 AndroidX 或 Android Support Library 库 ;
AppCompatActivity 是 FragmentActivity 的子类 , 而 FragmentActivity 又是 Activity 的子类 , 因此 AppCompatActivity 继承了 Activity 的所有功能和特性 , 并可以使用 Fragment , 其适应性比较广泛 ;
如果使用 AppCompatActivity 出现报错 , 不能使用 Activity 进行替换 , 而是使用 FragmentActivity ;