2022-06-20 18:59:22.201 20149-20149/com.xx.xxxx E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xx.xxxx, PID: 20149
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:681)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:681)
Caused by: org.koin.core.error.NoBeanDefFoundException: |- No definition found for class:'com.xx.xxxx.di.PreferencesManager'. Check your definitions!
at org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:304)
at org.koin.core.scope.Scope.resolveValue(Scope.kt:274)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:241)
at org.koin.core.scope.Scope.get(Scope.kt:204)
at com.xx.xxxx.SplashActivity$special$$inlined$inject$default$1.invoke(ComponentCallbackExt.kt:61)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.xx.xxxx.SplashActivity.getMyPref(SplashActivity.kt:16)
at com.xx.xxxx.SplashActivity.callNextScreen(SplashActivity.kt:28)
at com.xx.xxxx.SplashActivity.onCreate$lambda-0(SplashActivity.kt:24)
at com.xx.xxxx.SplashActivity.$r8$lambda$ZKKoKfwsv3qwgbmTc6lA0Ow_bOM(SplashActivity.kt)
at com.xx.xxxx.SplashActivity$$ExternalSyntheticLambda0.run(D8$$SyntheticClass)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:179)
at android.app.ActivityThread.main(ActivityThread.java:5730)
我正面临一些关于Koin DI的问题。
import android.app.Application
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.loadKoinModules
import org.koin.core.context.startKoin
//import org.koin.core.context.GlobalContext.startKoin
//import org.koin.android.ext.android.startKoin
class BaseApplication : Application() {
companion object {
lateinit var ins: BaseApplication
}
override fun onCreate() {
super.onCreate()
ins = this
startKoin {
androidContext(this@BaseApplication)
// modules(listOf(appModule, repoModule, viewModelModule))
val modules = listOf(
appModule
)
loadKoinModules(modules)
}
}
}
我的AppModuleClassBelow
val appModule = module {
single { provideAppPreference(androidApplication()) }
}
private fun provideAppPreference(application: Application): PreferencesManager {
val myPref = application.applicationContext.getSharedPreferences(
"Patient",
Context.MODE_PRIVATE
)
return PreferencesManager(myPref)
}
我的PreferenceManagerClass在下面
class PreferencesManager(private val myPref: SharedPreferences) {
companion object {
var KEY_AUTH_TOKEN = "auth_token"
var KEY_FCM_TOKEN = "fcm_token"
var KEY_USER_MODEL = "user_model"
}
fun isLogin(): Boolean {
return getUserModel()?.firstname?.isNotEmpty() == true
}
fun getMobileNumber(): String {
return getUserModel()?.phone ?: ""
}
fun getEmail(): String {
return getUserModel()?.email ?: ""
}
fun getUserName(): String {
return getUserModel()?.firstname ?: ""
}
fun getUserModel(): UserModel? {
return Gson().fromJson(getStringValue(KEY_USER_MODEL), UserModel::class.java)
}
fun setUserModel(userModel: UserModel?) {
val str = Gson().toJson(userModel, UserModel::class.java)
setStringValue(KEY_USER_MODEL, str)
}
fun getNameForPayment(): String {
val s = getUserName()
return if (s.isEmpty()) {
getStr(R.string.app_name)
} else {
s
}
}
fun getEmailForPayment(): String {
val s = getEmail()
return if (s.isEmpty()) {
"info@labsdone.com"
} else {
s
}
}
fun getMobileForPayment(): String {
val s = getMobileNumber()
return if (s.isEmpty() || s.length < 10) {
"9876543210"
} else {
s
}
}
fun resetCartList() {
val currentUserId = getStringValue("UserId")
myPref.edit().putString("cart_list$currentUserId", "").commit()
}
fun generateFCMToken() {
// myPref.saveFCM("Test fcmToken");
/*FirebaseMessaging.getInstance().token
.addOnCompleteListener { task: Task<String?> ->
if (!task.isSuccessful) {
setStringValue(PREF_KEY_FCM_TOKEN,"Fetching FCM registration token failed " + task.exception)
Log.w(ContentValues.TAG,"Fetching FCM registration token failed",task.exception)
return@addOnCompleteListener
}
// Get new FCM registration token
val fcmToken = task.result
if (fcmToken != null) {
if (fcmToken.isNotEmpty()) {
setStringValue(PREF_KEY_FCM_TOKEN,fcmToken)
} else {
setStringValue(PREF_KEY_FCM_TOKEN,"GetInstanceId Failed")
}
}
}*/
}
fun getLastReservationId(): String {
return getStringValue("reservationId")
}
fun setLastReservationId(token: String?) {
setStringValue("reservationId", token)
}
fun getLastStationId(): String {
return getStringValue("StationId")
}
fun setLastStationId(token: String?) {
setStringValue("StationId", token)
}
fun getAccessToken(): String {
return getStringValue(KEY_AUTH_TOKEN)
}
fun setAccessToken(token: String?) {
setStringValue(KEY_AUTH_TOKEN, token)
}
fun setStringValue(keyName: String?, value: String?) {
myPref.edit().putString(keyName, value).apply()
}
fun getStringValue(keyName: String?): String {
return AppValidator.toStr(myPref.getString(keyName, ""))
}
fun setBooleanValue(keyName: String?, value: Boolean) {
myPref.edit().putBoolean(keyName, value).apply()
}
fun getBooleanValue(keyName: String?): Boolean {
return myPref.getBoolean(keyName, false)
}
fun setIntValue(keyName: String?, value: Int) {
myPref.edit().putInt(keyName, value).apply()
}
fun getIntValue(keyName: String?): Int {
return myPref.getInt(keyName, 0)
}
fun remove(key: String?) {
myPref.edit().remove(key).apply()
}
fun clear(): Boolean {
return myPref.edit().clear().commit()
}
fun resetAllPref() {
clear()
}
}
我使用这个DI为我的应用程序存储一些信息。我已经在我的活动中注射了这个。就像下面。
private val myPref: PreferencesManager by inject()
但是当我试图访问它时,我会遇到上面提到的错误和应用程序崩溃。
你的帮助真的很感激。
编辑
我试着用不懒惰的方式注射。面对同样的错误。
private val myPref: PreferencesManager = get ()
编辑
当我在Splashactivity上注入之后进行调试时,我将得到以下响应,响应作为图像附加
延迟值未初始化但出现错误。
我在这件事上犯了什么错误吗?在这一行之后,app会以上述错误崩溃。
org.koin.core.error.NoBeanDefFoundException
编辑
如果我使用范围组件(如下面所示),而不是单一的,
val activityModule = module {
scope<SplashActivity> {
scoped<PreferencesManager> {
provideAppPreference(androidApplication())
}
}
}
private fun provideAppPreference(application: Application): PreferencesManager {
val myPref = application.applicationContext.getSharedPreferences(
"default",
Context.MODE_PRIVATE
)
return PreferencesManager(myPref)
}
注射如下,
class SplashActivity : AppCompatActivity(),AndroidScopeComponent{
override val scope: Scope by activityScope()
private val myPref:PreferencesManager by inject<PreferencesManager>()
private lateinit var binding: ActivitySplashBinding
// private val userViewModel:UsersViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySplashBinding.inflate(layoutInflater)
setContentView(binding.root)
changeStatusBarColor(getColorCompat(R.color.white), true)
// makeSendOtpReq()
Handler(Looper.getMainLooper()).postDelayed({
callNextScreen()
}, 5000)
}
private fun callNextScreen() {
if(!myPref.isLogin()){
startActivity(Intent(this, AuthActivity::class.java))
}else{
startActivity(Intent(this, MainActivity::class.java))
}
/* startActivity(Intent(this, MainActivity::class.java))
finish()
*/
}
}
这很好用。它并不是只适用于单一的。我也不知道原因。任何人都知道这意味着,提供反馈。
我会感谢你的帮助。
发布于 2022-06-22 19:58:19
我要先试一试,下面是我使用的代码:
// StackOverflow72688110App.kt
package com.trifork.stackoverflow72688110
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.loadKoinModules
import org.koin.core.context.startKoin
import org.koin.dsl.module
val appModule = module {
single {
val sharedPreferences = sharedPreferences("Patient", get())
PreferenceManager(sharedPreferences)
}
}
class PreferenceManager(private val sharedPreferences: SharedPreferences) {
fun printSomething() {
Log.d("PreferenceManager", "Hi from injected PreferenceManager")
Log.d("PreferenceManager", sharedPreferences.all.toString())
}
}
class StackOverflow72688110App : Application() {
override fun onCreate() {
super.onCreate()
val app = this
startKoin {
androidContext(app)
androidLogger()
loadKoinModules(appModule)
}
}
}
private fun sharedPreferences(prefsName: String, context: Context): SharedPreferences =
context.getSharedPreferences(prefsName, Context.MODE_PRIVATE)
// MainActivity.kt
package com.trifork.stackoverflow72688110
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import org.koin.android.ext.android.inject
class MainActivity : AppCompatActivity() {
private val preferenceManager by inject<PreferenceManager>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
preferenceManager.printSomething()
}
}
此代码产生的输出:
为什么你的不起作用?
android:name=".StackOverflow72688110App"
添加到AndroidManifest.xml
文件中的<application>
中。这确保了您的onCreate
方法将被调用,因此也会调用startKoin
。<?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:name=".StackOverflow72688110App"
...>
...
</application>
</manifest>
从您的活动中获取的import org.koin.android.ext.android.inject
android.preference.PreferenceManager
中存在一个不是您感兴趣的类。因此,请确保您正在为您的PreferenceManager
导入正确的包名
https://stackoverflow.com/questions/72688110
复制相似问题