Issue
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)
I am facing some issue on 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)
}
}
}
My 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)
}
My PreferenceManagerClass is below
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()) {
"[email protected]"
} 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()
}
}
I am using this DI for store some information for my app. I have inject this in my Activity. like below.
private val myPref: PreferencesManager by inject()
But when I try to access this, I am getting above mentioned error and app crashes.
Yours help really appreciated.
EDIT
I tried with not lazy type injection. facing the same Error.
private val myPref: PreferencesManager = get ()
EDIT
When I debug after injection on Splashactivity I am getting following response, response is attached as image
Lazy value not initialised yet error coming.
Did I make any mistake on this? after this line, app crashes with above error.
org.koin.core.error.NoBeanDefFoundException
EDIT
instead of single, if I used Scope component, like below,
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)
}
and the injection as follows,
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()
*/
}
}
this is working fine. it is not working on single only. I don't know why. Anybody know means, provide the feedback.
Helps will be appreciated.
Solution
I've got it to work first try, here's the code that I have used:
// 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()
}
}
The output that this code yields:
Now to why yours doesn't work?
- Make sure you've added
android:name=".StackOverflow72688110App"
to your<application>
in theAndroidManifest.xml
file. This ensures that youronCreate
method will be called and hence thestartKoin
as well.
<?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>
From your activity make sure your import for inject is
import org.koin.android.ext.android.inject
Make sure that the generic that you pass into the inject is the correct class of PreferenceManager. Note that exists a class in
android.preference.PreferenceManager
that is not the one you're interested in. So make sure you're importing the right package name for yourPreferenceManager
Answered By - Some random IT boy
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.