Kotlin lateinit属性未初始化异常:获取仓库实例致应用崩溃求助
问题求助:kotlin.UninitializedPropertyAccessException异常导致应用崩溃
在Activity中尝试从仓库获取实例时,应用因以下异常停止运行:
kotlin.UninitializedPropertyAccessException: lateinit property instance has not been initialized
相关代码
MyApp类代码
class MyApp : Application() { lateinit var userPreferences: UserPreferencesRepository companion object { @get:Synchronized lateinit var instance: MyApp private set } override fun onCreate() { super.onCreate() instance = this userPreferences = UserPreferencesRepository.getInstance(this) } }
UserPreferencesRepository类代码
class UserPreferencesRepository(context: Context){ private val sharedPreferences = context.applicationContext.getSharedPreferences(APP_SETTINGS_PREF, Context.MODE_PRIVATE) /** * Get the appTheme. By default, theme is set to follow system. */ val appTheme: Theme get() { val theme = sharedPreferences.getString(PREF_NAME_THEME_MODE, Theme.FOLLOW_SYSTEM.name) return Theme.valueOf(theme ?: Theme.FOLLOW_SYSTEM.name) } fun updateTheme(theme: Theme) { sharedPreferences.edit() .putString(PREF_NAME_THEME_MODE, theme.name) .apply() ThemeChanger().invoke(theme) } companion object { @Volatile private var INSTANCE: UserPreferencesRepository? = null fun getInstance(context: Context): UserPreferencesRepository { return INSTANCE ?: synchronized(this) { INSTANCE?.let { return it } val instance = UserPreferencesRepository(context) INSTANCE = instance instance } } } }
问题原因
这个异常核心是你在MyApp的instance属性还未完成初始化时,就尝试访问它了。常见触发场景:
- 代码中通过
MyApp.instance获取Application实例,但此时MyApp的onCreate还没执行(比如Activity初始化逻辑意外提前) AndroidManifest.xml中未正确注册MyApp,导致系统没有初始化这个Application类
解决方案
1. 检查并确保Application在Manifest中注册
打开AndroidManifest.xml,确认application标签的android:name属性指向MyApp类:
<application android:name=".MyApp" 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/Theme.MyApp"> <!-- 活动声明 --> </application>
2. 直接在Activity中获取仓库实例(推荐)
不需要依赖MyApp.instance,直接在Activity中传入自身Context调用仓库的getInstance方法:
// 示例:在Activity的onCreate中 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val userPrefs = UserPreferencesRepository.getInstance(this) // 使用userPrefs操作偏好设置 }
这种方式更灵活,也避免了对Application单例的强依赖。
3. 优化MyApp的单例逻辑(可选)
如果必须保留MyApp.instance,可以改用lazy初始化来避免未初始化异常,同时添加异常提示:
companion object { @get:Synchronized val instance: MyApp by lazy { throw IllegalStateException("请确保MyApp已在Manifest中正确注册") } }
不过这种方案不如方案2直接,仅在你有特殊场景需要全局Application实例时使用。
内容的提问来源于stack exchange,提问作者Mahmoud Nabil
相关产品推荐
相关产品推荐

