简体   繁体   中英

How to solver error for kotlin coroutines flow?

I tried to use NetworkBoundResource for my MVVM Model and after i follow some tutorial, i'm having an error look this

10-21 14:15:04.073 31376-31376/com.example.mvvmsecondmodel E/Process: android_os_Process_getProcessNameByPid pid is 31376
10-21 14:15:04.074 31376-31376/com.example.mvvmsecondmodel E/Process: android_os_Process_getProcessNameByPid value is mvvmsecondmodel
10-21 14:15:04.416 31376-31421/com.example.mvvmsecondmodel E/SQLiteLog: (283) recovered 8 frames from WAL file /data/data/com.example.mvvmsecondmodel/databases/movie_db-wal
10-21 14:15:04.640 31376-31376/com.example.mvvmsecondmodel E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.mvvmsecondmodel, PID: 31376
    java.lang.IllegalArgumentException: Unable to create call adapter for kotlinx.coroutines.flow.Flow<com.example.mvvmsecondmodel.data.respository.ApiResponse<com.example.mvvmsecondmodel.data.model.MovieResponse$Movie>>
        for method ApiService.getMyMovie
        at retrofit2.Utils.methodError(Utils.java:52)
        at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:105)
        at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:66)
        at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:37)
        at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)
        at retrofit2.Retrofit$1.invoke(Retrofit.java:149)
        at java.lang.reflect.Proxy.invoke(Proxy.java:397)
        at $Proxy0.getMyMovie(Unknown Source)
        at com.example.mvvmsecondmodel.data.remote.ApiService$DefaultImpls.getMyMovie$default(ApiService.kt:11)
        at com.example.mvvmsecondmodel.data.respository.MovieRespository$getListMovie$$inlined$networkBoundResource$1.invokeSuspend(NetworkBoundResource.kt:49)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:55)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
     Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for kotlinx.coroutines.flow.Flow<com.example.mvvmsecondmodel.data.respository.ApiResponse<com.example.mvvmsecondmodel.data.model.MovieResponse$Movie>>.
      Tried:
       * retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
       * retrofit2.DefaultCallAdapterFactory
        at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:241)
        at retrofit2.Retrofit.callAdapter(Retrofit.java:205)
        at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:103)
            ... 14 more

At first i thought there's red sign at my code so i checked ApiService and Respository class and nothing wrong cause i already follow the tutorial

ApiService:

interface ApiService {
    @GET("3/movie/popular")
    fun getMyMovie(@Query("api_key") api : String = "32bbbffe944d16d1d2a3ee46cfc6aaa0"
    ) : Flow<ApiResponse<MovieResponse.Movie>>
}

MovieRespository:

class MovieRespository (val apiService: ApiService, val movieDao: MovieDao) {

    fun getListMovie() : Flow<Resource<Movie>> {
        return networkBoundResource(
                fetchFromLocal = { movieDao.getMyMovie() },
                shouldFetchFromRemote = {true},
                fetchFromRemote = {apiService.getMyMovie()},
                processRemoteResponse = {},
                saveRemoteData = {movieDao.insert(
                        it.results.let {
                            it.map { data -> Movie.from(data) }
                        }
                )},
                onFetchFailed = {_, _ ->}
        ).flowOn(Dispatchers.IO)
    }

You should define your api service as suspend function.

Api Service:

interface ApiService {
    
    @GET("3/movie/popular")
    suspend fun getMyMovie(@Query("api_key") api : String = "32bbbffe944d16d1d2a3ee46cfc6aaa0"
    ) : ApiResponse<MovieResponse.Movie>

}

Movie Repository:

class MovieRepository (val apiService: ApiService, val movieDao: MovieDao) {

    fun getListMovie() : Flow<Resource<Movie>> {
        return flow {
            // do your networkBoundResource functions
            
        }.flowOn(Dispatchers.IO)
    }

I can't test the code because you didn't share your NetworkBoundResource class. I hope the code help to fix your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM