Kotlin中lateinit属性binding未初始化异常解决求助
解决kotlin.UninitializedPropertyAccessException:lateinit属性binding未初始化问题
运行com.example.organizeme应用时触发kotlin.UninitializedPropertyAccessException,提示lateinit属性binding未初始化,导致SplashActivity无法启动。
错误日志
FATAL EXCEPTION: main Process: com.example.organizeme, PID: 6281 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.organizeme/com.example.organizeme.SplashActivity}: kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) Caused by: kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized at com.example.organizeme.SplashActivity.onCreate(SplashActivity.kt:31) at android.app.Activity.performCreate(Activity.java:6662) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
相关代码
SplashActivity.kt
package com.example.organizeme import android.annotation.SuppressLint import android.graphics.Typeface import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.WindowInsets import android.view.WindowManager import com.example.organizeme.databinding.ActivitySplashBinding @SuppressLint("CustomSplashScreen") class SplashActivity : AppCompatActivity() { private lateinit var binding: ActivitySplashBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_splash) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { window.insetsController?.hide(WindowInsets.Type.statusBars()) } else { @Suppress("DEPRECATION") window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN ) } val view = binding.root setContentView(view) val typeFace : Typeface = Typeface.createFromAsset(assets, "carbon bl.otf") binding.tvAppName.typeface = typeFace } }
activity_splash.xml
<?xml version="1.0" encoding="utf-8"?> <!--suppress XmlUnusedNamespaceDeclaration --> <LinearLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:background="@drawable/splash_screen" tools:context=".SplashActivity"> <TextView android:id="@+id/tvAppName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="@string/app_name" android:textColor="@android:color/white" android:textSize="@dimen/splash_screen_title_text_size" android:textStyle="bold" /> </LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.OrganizeMe" tools:targetApi="31"> <activity android:name=".SplashActivity" android:screenOrientation="fullSensor" android:exported="true" android:label="@string/title_activity_splash" android:theme="@style/Theme.OrganizeMe" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity" android:exported="true"> </activity> </application> </manifest>
解决方案
问题根源是lateinit修饰的binding变量未初始化就被调用。ViewBinding的正确用法是先通过inflate方法初始化实例,再设置布局。具体修改步骤:
- 替换原有的
setContentView(R.layout.activity_splash)为ViewBinding初始化代码:binding = ActivitySplashBinding.inflate(layoutInflater) setContentView(binding.root) - 移除代码中重复的
setContentView(view)调用,避免重复设置布局。
修改后的完整SplashActivity.kt代码:
package com.example.organizeme import android.annotation.SuppressLint import android.graphics.Typeface import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.WindowInsets import android.view.WindowManager import com.example.organizeme.databinding.ActivitySplashBinding @SuppressLint("CustomSplashScreen") class SplashActivity : AppCompatActivity() { private lateinit var binding: ActivitySplashBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 初始化ViewBinding并设置布局 binding = ActivitySplashBinding.inflate(layoutInflater) setContentView(binding.root) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { window.insetsController?.hide(WindowInsets.Type.statusBars()) } else { @Suppress("DEPRECATION") window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN ) } val typeFace : Typeface = Typeface.createFromAsset(assets, "carbon bl.otf") binding.tvAppName.typeface = typeFace } }
解释:
ActivitySplashBinding.inflate(layoutInflater)会根据布局文件生成对应的Binding实例,绑定所有布局中的ViewsetContentView(binding.root)将Binding的根View设置为Activity的布局- 后续通过
binding.tvAppName即可直接访问布局中的TextView,无需调用findViewById
内容的提问来源于stack exchange,提问作者Gurasis Singh
相关产品推荐
相关产品推荐

