前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【错误记录】Android 编译报错 ( Attempt to invoke virtual method ‘void xx.ActionBar.setTitle()‘ on a null obj )

【错误记录】Android 编译报错 ( Attempt to invoke virtual method ‘void xx.ActionBar.setTitle()‘ on a null obj )

作者头像
韩曙亮
发布2024-04-20 08:47:08
2050
发布2024-04-20 08:47:08
举报

一、报错信息

在 Android Studio 中 , 使用右键菜单 , 创建 " Bottom Navigation Activity " ,

创建完成后 , 启动该 Activity , 报如下错误 :

代码语言:javascript
复制
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: cn.zkhw.client, PID: 30022
    java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.zkhw.client/cn.zkhw.client.BottomNavigationActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.appcompat.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
        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: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.appcompat.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
        at androidx.navigation.ui.ActionBarOnDestinationChangedListener.setTitle(ActionBarOnDestinationChangedListener.java:48)
        at androidx.navigation.ui.AbstractAppBarOnDestinationChangedListener.onDestinationChanged(AbstractAppBarOnDestinationChangedListener.java:103)
        at androidx.navigation.NavController.addOnDestinationChangedListener(NavController.java:233)
        at androidx.navigation.ui.NavigationUI.setupActionBarWithNavController(NavigationUI.java:227)
        at androidx.navigation.ui.ActivityKt.setupActionBarWithNavController(Activity.kt:74)
        at cn.zkhw.client.BottomNavigationActivity.onCreate(BottomNavigationActivity.kt:32)
        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) 

二、问题分析

生成的布局文件代码如下 :

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

    <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" />

</androidx.constraintlayout.widget.ConstraintLayout>

生成的主界面代码如下 :

代码语言:javascript
复制
import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import cn.zkhw.client.databinding.ActivityBottomNavigationBinding

class BottomNavigationActivity : AppCompatActivity() {

    private lateinit var binding: ActivityBottomNavigationBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityBottomNavigationBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val navView: BottomNavigationView = binding.navView

        val navController = findNavController(R.id.nav_host_fragment_activity_bottom_navigation)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }
}

报错的代码是

代码语言:javascript
复制
setupActionBarWithNavController(navController, appBarConfiguration)

报错信息 :

代码语言:javascript
复制
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.appcompat.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
        at androidx.navigation.ui.ActionBarOnDestinationChangedListener.setTitle(ActionBarOnDestinationChangedListener.java:48)
        at androidx.navigation.ui.AbstractAppBarOnDestinationChangedListener.onDestinationChanged(AbstractAppBarOnDestinationChangedListener.java:103)
        at androidx.navigation.NavController.addOnDestinationChangedListener(NavController.java:233)
        at androidx.navigation.ui.NavigationUI.setupActionBarWithNavController(NavigationUI.java:227)
        at androidx.navigation.ui.ActivityKt.setupActionBarWithNavController(Activity.kt:74)
        at cn.zkhw.client.BottomNavigationActivity.onCreate(BottomNavigationActivity.kt:32)

分析上述报错信息 , 可以得知 , 尝试调用 androidx.appcompat.app.ActionBar 的 void setTitle() 方法 , 但是 androidx.appcompat.app.ActionBar 对象是空的 , 直接报空指针异常 ;

进入 setupActionBarWithNavController(navController, appBarConfiguration) 方法中 , 分析其代码 :

代码语言:javascript
复制
fun AppCompatActivity.setupActionBarWithNavController(
    navController: NavController,
    configuration: AppBarConfiguration = AppBarConfiguration(navController.graph)
) {
    NavigationUI.setupActionBarWithNavController(this, navController, configuration)
}

在上述代码中调用了 NavigationUI.setupActionBarWithNavController() 方法 , 这是 Navigation 中的常用方法 , 用于将 NavigationView 和 NavigationController 和 ActionBar 关联起来 ;

此处没有获取到 ActionBar 对象 , ActionBar 是页面顶部的 标题栏 ;

在 Android Studio 中生成的代码 , 一般都是标准代码 , 不会出错 , 这里出现问题大概率是自己在项目中的其它设置导致的 ;

检查 AndroidManifest.xml 中的 Theme 主题设置 , 在 application 标签中 , 设置了 Theme.AppCompat.Light.NoActionBar 标题 , 这就是此时的报错原因 ,

代码语言:javascript
复制
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar"
        android:usesCleartextTraffic="true">

设置了 Theme.AppCompat.Light.NoActionBar 主题 , 肯定是没有 ActionBar 的 , 因此这里尝试调用 androidx.appcompat.app.ActionBar 的 setTitle() 方法直接报空指针异常 ;

三、解决方案

1、配置有标题的主题 - Theme.AppCompat.Light.DarkActionBar

为报错的 Activity 单独配置一个

代码语言:javascript
复制
Theme.AppCompat.Light.DarkActionBar

主题 , 这样该 Activity 就会有 ActionBar , 就不会报错了 ;

代码语言:javascript
复制
        <activity
            android:name=".NavigationActivity"
            android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
            android:label="@string/title_activity_bottom_navigation"></activity>

执行效果如下图所示 :

2、不关联 Navigation 与 ActionBar

在上述代码中 , 调用了 NavigationUI.setupActionBarWithNavController 函数 , 关联了 Navigation 与 ActionBar , 这里可以调用其他的关联方法 ,

调用 NavigationUI.setupWithNavController() 方法 , 可以只关联 NavigationView 与 NavigationController , 不需要关联 ActionBar ,

此外 上述代码 与 navView.setupWithNavController(navController) 效果相同 , 这里可以注释掉 setupActionBarWithNavController(navController, appBarConfiguration) 代码 , 此时就不会因为找到 ActionBar 而报空指针异常 ;

注释掉上述代码后 , 效果如下 :

代码语言:javascript
复制
class BottomNavigationActivity : AppCompatActivity() {

    private lateinit var binding: ActivityBottomNavigationBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityBottomNavigationBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val navView: BottomNavigationView = binding.navView

        val navController = findNavController(R.id.nav_host_fragment_activity_bottom_navigation)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
            )
        )

        //setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }
}

运行效果如下 :

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、报错信息
  • 二、问题分析
  • 三、解决方案
    • 1、配置有标题的主题 - Theme.AppCompat.Light.DarkActionBar
      • 2、不关联 Navigation 与 ActionBar
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档