1

Is there any way to make retrofit2 return livedata instead of Observable ?

If it's possible how we can implement this approach?

If it's not possible, Is it recommanded to make retrofit return Observable then convert it to livedata?

Ali Habbash
  • 777
  • 2
  • 6
  • 29

2 Answers2

3

You have to add addCallAdapterFactory(LiveDataCallAdapterFactory()) in Retrofit Adapter.

I have implemented using Dagger-2:-

@Module(includes = [ViewModelModule::class])
        class AppModule {
        @Singleton
        @Provides
        fun provideGithubService(): GithubService {
            return Retrofit.Builder()
                .baseUrl("YOUR URL")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(LiveDataCallAdapterFactory())
                .build()
                .create(GithubService::class.java)
        }
      }

Create an interface class like GithubService:-

interface GithubService {
    @GET("users/{login}")
    fun getUser(@Path("login") login: String): LiveData<ApiResponse<User>>
}

Inject GithubService class and then you can get :-

githubService.getUser(login)

LiveDataCallAdapterFactory will be like this

import androidx.lifecycle.LiveData
import com.android.example.github.api.ApiResponse
import retrofit2.CallAdapter
import retrofit2.CallAdapter.Factory
import retrofit2.Retrofit
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

class LiveDataCallAdapterFactory : Factory() {
    override fun get(
            returnType: Type,
            annotations: Array<Annotation>,
            retrofit: Retrofit
    ): CallAdapter<*, *>? {
        if (Factory.getRawType(returnType) != LiveData::class.java) {
            return null
        }
        val observableType = Factory.getParameterUpperBound(0, returnType as ParameterizedType)
        val rawObservableType = Factory.getRawType(observableType)
        if (rawObservableType != ApiResponse::class.java) {
            throw IllegalArgumentException("type must be a resource")
        }
        if (observableType !is ParameterizedType) {
            throw IllegalArgumentException("resource must be parameterized")
        }
        val bodyType = Factory.getParameterUpperBound(0, observableType)
        return LiveDataCallAdapter<Any>(bodyType)
    }
}

For reference you can see this link https://github.com/googlesamples/android-architecture-components/tree/master/GithubBrowserSample

Alok Mishra
  • 1,904
  • 1
  • 17
  • 18
1

You can use LiveDataReactiveStreams.

For example:

    fun someMethod(id : Int) : LiveData<List<SomeObject>>{
        return LiveDataReactiveStreams.fromPublisher(
            repository.getDataFromSource(id)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()))
    }

Here, repository.getDataFromSource() returns a Flowable.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
Reema
  • 11
  • 3