web-dev-qa-db-fra.com

Causée par: org.koin.core.error.instancecreationException: Impossible de créer une instance pour [Type: usine, primaire_type

Je développe une application d'information que j'ai mis en œuvre Koin avec viewModel dans la classe de fragments, mais je reçois la suite d'erreur lorsque je teste le code sur l'émulateur

 Java.lang.RuntimeException: Java.lang.reflect.InvocationTargetException
        at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:557)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:922)
     Caused by: Java.lang.reflect.InvocationTargetException
        at Java.lang.reflect.Method.invoke(Native Method)
        at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:547)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:922) 
     Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [type:Factory,primary_type:'yodgorbek.komilov.musobaqayangiliklari.viewmodel.MainViewModel']
        at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:61)
        at org.koin.core.instance.FactoryDefinitionInstance.get(FactoryDefinitionInstance.kt:37)
        at org.koin.core.definition.BeanDefinition.resolveInstance(BeanDefinition.kt:70)
        at org.koin.core.scope.Scope.resolveInstance(Scope.kt:165)
        at org.koin.core.scope.Scope.get(Scope.kt:128)
        at org.koin.androidx.viewmodel.ViewModelResolutionKt$createViewModelProvider$1.create(ViewModelResolution.kt:66)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.Java:164)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.Java:130)
        at org.koin.androidx.viewmodel.ViewModelResolutionKt.getInstance(ViewModelResolution.kt:43)
        at org.koin.androidx.viewmodel.ViewModelResolutionKt.getViewModel(ViewModelResolution.kt:23)
        at org.koin.androidx.viewmodel.ext.Android.LifecycleOwnerExtKt.getViewModel(LifecycleOwnerExt.kt:85)
        at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment$$special$$inlined$viewModel$1.invoke(LifecycleOwnerExt.kt:95)
        at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment$$special$$inlined$viewModel$1.invoke(Unknown Source:0)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment.getViewModel(Unknown Source:7)
        at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment.initViewModel(TopHeadlinesFragment.kt:57)
        at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment.onCreateView(TopHeadlinesFragment.kt:51)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.Java:2600)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.Java:881)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.Java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.Java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.Java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.Java:2079)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.Java:1869)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.Java:1824)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.Java:1727)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.Java:2663)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.Java:2613)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.Java:246)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.Java:542)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.Java:201)
        at Android.app.Instrumentation.callActivityOnStart(Instrumentation.Java:1392)
        at Android.app.Activity.performStart(Activity.Java:7252)
        at Android.app.ActivityThread.handleStartActivity(ActivityThread.Java:3000)
        at Android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.Java:185)
        at Android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.Java:170)
2019-11-16 15:12:01.728 12995-12995/yodgorbek.komilov.musobaqayangiliklari E/AndroidRuntime:     at Android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.Java:147)
        at Android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.Java:73)
        at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1858)
        at Android.os.Handler.dispatchMessage(Handler.Java:106)
        at Android.os.Looper.loop(Looper.Java:201)
        at Android.app.ActivityThread.main(ActivityThread.Java:6820)
            ... 3 more
     Caused by: org.koin.core.error.NoBeanDefFoundException: No definition found for 'Java.lang.Object' has been found. Check your module definitions.
        at org.koin.core.scope.Scope.findDefinition(Scope.kt:170)
        at org.koin.core.scope.Scope.resolveInstance(Scope.kt:164)
        at org.koin.core.scope.Scope.get(Scope.kt:128)
        at yodgorbek.komilov.musobaqayangiliklari.di.application.module.AppModulesKt$appModules$1$3.invoke(appModules.kt:65)
        at yodgorbek.komilov.musobaqayangiliklari.di.application.module.AppModulesKt$appModules$1$3.invoke(Unknown Source:4)
        at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:54)
            ... 44 more

ci-dessous TopheadLinesFragment.kt

classe TopHeadLinesFragment: Fragment () {

private val viewModel: MainViewModel by viewModel()
private lateinit var topHeadlinesAdapter: TopHeadlinesAdapter


//3
override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val view = inflater.inflate(
        R.layout.fragment_top_headlines
        , container, false
    )


    val recyclerView = view.findViewById(R.id.recyclerView) as RecyclerView
    val pb = view.findViewById(R.id.pb) as ProgressBar
    topHeadlinesAdapter = TopHeadlinesAdapter(recyclerView.context)
    recyclerView.layoutManager = LinearLayoutManager(context)
    recyclerView.adapter = topHeadlinesAdapter
    initViewModel()

    return view
}

private fun initViewModel() {
    viewModel?.sportList?.observe(this, Observer { newList ->
        topHeadlinesAdapter.updateData(newList)
    })

    viewModel?.showLoading?.observe(this, Observer { showLoading ->
        pb.visibility = if (showLoading) View.VISIBLE else View.GONE
    })

    viewModel?.showError?.observe(this, Observer { showError ->
        (showError)
    })

    viewModel?.loadNews()
}

}

ci-dessous MainviewModel.kt

Suppress("UNCHECKED_CAST")
class MainViewModel(newsRepository: Any?) : ViewModel(), CoroutineScope {
    // Coroutine's background job
     val job = Job()
     val sportNewsInterface: SportNewsInterface? = null
    // Define default thread for Coroutine as Main and add job
    override val coroutineContext: CoroutineContext = Dispatchers.Main + job

     val showLoading = MutableLiveData<Boolean>()
     val sportList = MutableLiveData <List<Article>>()
    val showError = SingleLiveEvent<String>()



    fun loadNews(

    ) {
        // Show progressBar during the operation on the MAIN (default) thread
        showLoading.value = true
        // launch the Coroutine
        launch {
            // Switching from MAIN to IO thread for API operation
            // Update our data list with the new one from API
            val result = withContext(Dispatchers.IO) {
                sportNewsInterface?.getNews()
            }
            // Hide progressBar once the operation is done on the MAIN (default) thread
            showLoading.value = false
            when (result) {

                is UseCaseResult.Success<*> -> {
                    sportList.value = result.data as List<Article>
                }
                is Error -> showError.value = result.message
            }
        }


    }

    override fun onCleared() {
        super.onCleared()
        // Clear our job when the linked activity is destroyed to avoid memory leaks
        job.cancel()
    }
}

ci-dessous Appmodules.kt

const val BASE_URL = "https://newsapi.org/"

val appModules = module {
    // The Retrofit service using our custom HTTP client instance as a singleton
    single {
        createWebService<SportNewsInterface>(
            okHttpClient = createHttpClient(),
            factory = RxJava2CallAdapterFactory.create(),
            baseUrl = BASE_URL
        )
    }
    // Tells Koin how to create an instance of CatRepository
    factory<NewsRepository> { (NewsRepositoryImpl(sportNewsInterface = get())) }
    // Specific viewModel pattern to tell Koin how to build MainViewModel
    viewModel { MainViewModel (newsRepository = get ())  }
}

/* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
fun createHttpClient(): OkHttpClient {
    val client = OkHttpClient.Builder()
    client.readTimeout(5 * 60, TimeUnit.SECONDS)
    return client.addInterceptor {
        val original = it.request()
        val requestBuilder = original.newBuilder()
        requestBuilder.header("Content-Type", "application/json")
        val request = requestBuilder.method(original.method, original.body).build()
        return@addInterceptor it.proceed(request)
    }.build()
}

/* function to build our Retrofit service */
inline fun <reified T> createWebService(
    okHttpClient: OkHttpClient,
    factory: CallAdapter.Factory, baseUrl: String
): T {
    val retrofit = Retrofit.Builder()
        .baseUrl(baseUrl)
        .addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .addCallAdapterFactory(factory)
        .client(okHttpClient)
        .build()
    return retrofit.create(T::class.Java)
}

ci-dessous NewsRePository.kt où j'ai mis en œuvre un journal

interface NewsRepository {
    // Suspend is used to await the result from Deferred
    suspend fun getNewsList(): UseCaseResult<Deferred<List<SportNewsResponse>>>
}

class NewsRepositoryImpl(private val sportNewsInterface: SportNewsInterface) : NewsRepository {
    override suspend fun getNewsList(): UseCaseResult<Deferred<List<SportNewsResponse>>> {
        /*
         We try to return a list of cats from the API
         Await the result from web service and then return it, catching any error from API
         */
        return try {
            val result = sportNewsInterface.getNews()
            UseCaseResult.Success(result) as UseCaseResult<Deferred<List<SportNewsResponse>>>
        } catch (ex: Exception) {
            UseCaseResult.Error(ex)
        }
    }
}
5
sashabeliy

Vous devez utiliser la convention "Fournir" comme avec Dagger @Provides Annotation comme dans l'exemple ci-dessous.

val appModules = module {

    fun provideNewsRepository(sportNewsInterface: SportNewsInterface): NewsRepository {

        return NewsRepositoryImpl(sportNewsInterface)
    }

    fun provideSportNewsInterface(): SportNewsInterface {
        return createWebService < SportNewsInterface > (
            okHttpClient = createHttpClient(),
            factory = RxJava2CallAdapterFactory.create(),
            baseUrl = BASE_URL
        )
    }

    single {
        provideNewsRepository(get())
    }
    single {
        provideSportNewsInterface()
    }
    viewModel {
        MainViewModel(newsRepository = get())
    }
}
0
Etukeni E. Ndecha O

Vous avez peut-être oublié de créer une instance de l'interface API dans le module de réseautage. Ma classe de module de réseau ressemble à ceci,

val networkingModule = module {
    single { GsonConverterFactory.create() as Converter.Factory }
    single { HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY) as Interceptor }
    single {
        OkHttpClient.Builder().apply {
            if (BuildConfig.DEBUG) addInterceptor(get())
                .callTimeout(10, TimeUnit.SECONDS)
        }.build()
    }
    single {
        Retrofit.Builder()
            .baseUrl(BuildConfig.Host)
            .client(get())
            .addConverterFactory(get())
            .build()
    }
    single { get<Retrofit>().create(LoginService::class.Java) }
    single { get<Retrofit>().create(BlockService::class.Java) }
    single { get<Retrofit>().create(ForgotPasswordService::class.Java) }
}
0
Varun Chandran

Dans mon cas, j'ai corrigé cela ajoutant un /. J'ai changé de

single(named("baseUrl")) { "https://yourwebsite.net/api" }

à

single(named("baseUrl")) { "https://yourwebsite.net/api/" }
0
Cabezas