Infinite updating of the RecyclerView list - android

With the help of dagger and rxJava I update the list in a RecyclerView. Everything works well, the list is displayed. But the problem is that in the logs I see how this list is updated every second. What could be the problem? In a similar project but in Java everything works correctly, the list is updated once at startup.
My Network Module:
#Module(includes = [ViewModelModule::class])
class NetworkModule {
companion object {
const val KEY = "key"
const val BASE_URL = "base_url"
}
#Provides
#Singleton
fun provideOkHttp(): OkHttpClient {
val httpClient = OkHttpClient.Builder()
httpClient.addInterceptor(object : Interceptor {
#Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
val original = chain.request()
val originalHttpUrl = original.url
val url = originalHttpUrl.newBuilder()
//.addQueryParameter("apikey", KEY)
.build()
val requestBuilder = original.newBuilder()
.url(url)
.header("apikey", KEY)
val request = requestBuilder.build()
return chain.proceed(request)
}
})
// logging interceptor
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
httpClient.addInterceptor(logging)
return httpClient.build()
}
#Provides
#Singleton
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(provideOkHttp())
.build()
}
#Provides
#Singleton
fun provideContactsService(retrofit: Retrofit) : ContactsService{
return retrofit.create(ContactsService::class.java)
}
}
My ViewModel:
class ContactsViewModel #Inject constructor(private val contactsRepository: ContactsRepository) :
ViewModel() {
var mutableLiveData = MutableLiveData<List<ContactsModel>>()
private val disposable = CompositeDisposable()
fun getContactMutableLiveData(): MutableLiveData<List<ContactsModel>> {
loadData()
return mutableLiveData
}
fun loadData() {
disposable.add(contactsRepository.modelSingle()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object : DisposableSingleObserver<List<ContactsModel>>() {
override fun onSuccess(t: List<ContactsModel>) {
getContactMutableLiveData().value = t
}
override fun onError(e: Throwable) {
}
})
)
}
}
And my Activity:
contactsViewModel.getContactMutableLiveData().observe(this#ContactListActivity, Observer {
mAdapter = ContactsAdapter(this#ContactListActivity, it as ArrayList<ContactsModel>)
recycler_contacts.layoutManager =
LinearLayoutManager(applicationContext, OrientationHelper.VERTICAL, false)
recycler_contacts.adapter = mAdapter
recycler_contacts.setHasFixedSize(true)
mAdapter.sortByName()
})

Okay if you only want to update your data list only once... I would recommend you look into a single live event that would trigger the reloading of your recycler view
As such
//in repo
private SingleLiveEvent<Boolean> listHasBeenUpdate=new SingleLiveEvent<>();
//setItsGetterInTheRepo
public SingleLiveEvent<Boolean> getListHasBeenUpdated(){
return listHasBeenUpdated();
}
//uponSucessfuly fetching your list from retrofit
listHasBeenUpdated=true;
//pass list to viewmodel
then in the ViewModel, I would set the list to be an Observable Data which would be updated once it's fetched from retrofit (Consider using room db to store this)
//use a setter to set the list from Repo
ObservableField<List<Contacts>> list=new ObservableField<>();
public SingleLiveEvent<List<Contacts>> fetchContacts(){
return myRepo.getListHasBeenUpdated();
}
In your activity class now observe the single live event like so
viewModel.fetchContacts().observe(this,contacts->{
if(contacts){
//update Recycler
}
});
hope this helps you.

It was a logical error. You need to rewrite the loadData function as shown below
class ContactsViewModel #Inject constructor(private val contactsRepository: ContactsRepository) :
ViewModel() {
var mutableLiveData = MutableLiveData<List<ContactsModel>>()
private val disposable = CompositeDisposable()
fun getContactMutableLiveData(): MutableLiveData<List<ContactsModel>> {
disposable.add(contactsRepository.modelSingle()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object : DisposableSingleObserver<List<ContactsModel>>() {
override fun onSuccess(t: List<ContactsModel>) {
mutableLiveData.value = t
}
override fun onError(e: Throwable) {
}
}))
return mutableLiveData
}
}

Related

Kotlin coroutines doesn't work with retrofit - no response

I'm trying to learn coroutines with retrofit and hilt.
There is simple api github https://api.github.com/users/JakeWharton/repos
But my code give in log:
D/OkHttp: --> GET https://api.github.com/users/JakeWharton/repos
D/OkHttp: --> END GET
without any reponse, despite the fact that using postman I get list with repos.
In my function loadData() debugger stop on the 1st lane, it doesn't come to println, something is wrong but don't know what.
my codes:
#Provides
fun provideGitHubService(retrofit: Retrofit): GitHubService{
return retrofit.create(GitHubService::class.java)
}
#Provides
fun provideOkHttpClient(): OkHttpClient {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return OkHttpClient
.Builder()
.addInterceptor(loggingInterceptor)
.build()
}
#Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl("https://github.com") // don't know how to remove it but it will be override anyway
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
}
private fun getRepos() {
viewModelScope.launch {
loadData()
}
}
private suspend fun loadData() {
val response = service.getRepos()
println(response). //debugger doesn't come here
}
interface GitHubService {
#GET("https://api.github.com/users/JakeWharton/repos")
suspend fun getRepos() : Call<List<User>>
}
data class User(
#SerializedName("name") val name: String
)
You don't need Call when using suspend. Please update the getRepos to:
// annotations omitted
suspend fun getRepos() : List<User>
I think you did something wrong in the instance of retrofit. try this.
class User {
#Expose
#SerializedName("name")
var name: String? = null
}
interface GitHubService {
#GET("users/JakeWharton/repos")
suspend fun getRepos(): Call<List<User>>
}
fun provideGitHubService(retrofit: Retrofit): GitHubService{
return retrofit.create(GitHubService::class.java)
}
class Example {
private val TAG = "Example"
/* OKHTTP CLIENT */
private fun provideOkHttpClient(): OkHttpClient {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return OkHttpClient
.Builder()
.addInterceptor(loggingInterceptor)
.build()
}
/* RETROFIT INSTANCE */
private fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.github.com/") // don't know how to remove it but it will be override anyway
.addConverterFactory(GsonConverterFactory.create())
.client(provideOkHttpClient())
.build()
}
/* LOADING DATA */
suspend fun loadData() {
val apiInterface = provideGitHubService(provideRetrofit())
val call: Call<List<User>> = apiInterface.getRepos()
call.enqueue( object : Callback<List<User>> {
override fun onResponse(call: Call<List<User>>, response: Response<List<User>>) {
for (users in response.body()!!){
Log.e(TAG, "NAME: ${users.name}")
}
}
override fun onFailure(call: Call<List<User>>, t: Throwable) {
Log.e(TAG, "onFailure: ${t.message}")
}
})
}
}

Scarlet websocket in Android application with coroutine

I'm trying to implement application, which will work with websocket. So I choose scarlet. I can see in logs a response from a server, but I cant consume a data in my viewModel. How to do that? I am using Koin + viewModel + coroutine
Module for Koin
val networkModule = module {
single { createScarlet() }
single <ChatSocketRepository> {
ChatSocketRepositoryImpl(get())
}
}
private fun createScarlet(): ChatSocketApi {
val client = OkHttpClient.Builder()
.readTimeout(DataProviderImplementation.TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DataProviderImplementation.TIMEOUT, TimeUnit.SECONDS)
.connectTimeout(DataProviderImplementation.TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()
return Scarlet.Builder()
.webSocketFactory(client.newWebSocketFactory("wss://demos.kaazing.com/echo"))
.addMessageAdapterFactory(GsonMessageAdapter.Factory())
.addStreamAdapterFactory(CoroutinesStreamAdapterFactory())
.build()
.create()
}
ChatSocketApi
interface ChatSocketApi {
#Receive
fun observeText(): ReceiveChannel<String>
}
ChatSocketRepository
interface ChatSocketRepository {
fun observeTest(): ReceiveChannel<String>
}
ChatSocketRepositoryImpl:
class ChatSocketRepositoryImpl(private val api: ChatSocketApi) : ChatSocketRepository {
override fun observeTest(): ReceiveChannel<String> {
return api.observeText()
}
}
ViewModel
class MyViewModel(private val chatSocketRepository: ChatSocketRepository) : BaseViewModel() {
init {
viewModelScope.launch {
val text = chatSocketRepository.observeTest().consumeEach {
Log.d("SOCKET", it.toString())
}
}
}
you already get the data, and your data is String because you declare ReceiveChannel<String> you can use the received data and put it in a LiveData. change the value of livedata in the .consumeEach{} method instead.

progress bar loading not showing response from server?

I am developing news app but TopHeadlinesFragment loading progress bar not showing response from server
what I want to know where I am making mistake what I have to do in order to show response from server. Maybe something wrong with my observer in topHeadlinesFragment.kt or koin network module
below my screenshot of the app
loading progress
below my TopHeadlinesFragment.kt
class TopHeadlinesFragment : Fragment() {
private lateinit var binding: FragmentTopHeadlinesBinding
private val viewModel by viewModel<MainViewModel>()
private lateinit var topHeadlinesAdapter: TopHeadlinesAdapter
// private val newsRepository: NewsRepository by inject()
//3
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding =
DataBindingUtil.inflate(inflater, R.layout.fragment_top_headlines, container, false)
binding.lifecycleOwner = this
topHeadlinesAdapter = TopHeadlinesAdapter()
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViewModel()
// loadingAds()
}
private fun initViewModel() {
viewModel.sportList.observe(this, Observer { result ->
when (result) {
is Results.Success -> {
val newList = result.data
if (newList != null) {
topHeadlinesAdapter.updateData(newList)
}
binding.recyclerView.adapter = topHeadlinesAdapter
topHeadlinesAdapter.notifyDataSetChanged()
viewModel.showLoading.observe(this, Observer {showLoading ->
pb.visibility = if (showLoading) View.VISIBLE else View.GONE
})
}
is Results.Failure -> {
viewModel.showLoading.observe(this, Observer {showLoading ->
pb.visibility = if (showLoading) View.INVISIBLE else View.GONE
})
}
}
viewModel.loadNews()
})
}
}
below NewsRepository.kt
class NewsRepository(
private val sportNewsApi: SportNewsInterface,
private val sportNewsDao: SportNewsDao
) {
companion object{
const val TAG= "Error"
}
val data = sportNewsDao.getAllData()
suspend fun refresh() = withContext(Dispatchers.IO) {
val articles = sportNewsApi.getNewsAsync().body()?.articles
if (articles != null) {
sportNewsDao.addAll(articles)
Log.e(TAG,"Error")
Results.Success(articles)
} else {
Results.Failure("MyError")
}
}
}
below My MainViewModel.kt
class MainViewModel(val newsRepository: NewsRepository) : ViewModel(), CoroutineScope {
// Coroutine's background job
val job = Job()
// Define default thread for Coroutine as Main and add job
override val coroutineContext: CoroutineContext = Dispatchers.Main + job
private val _showLoading = MutableLiveData<Boolean>()
private val _sportList = MutableLiveData<Results>()
val showLoading: LiveData<Boolean>
get() = _showLoading
val sportList: LiveData<Results>
get() = _sportList
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 = newsRepository.refresh()
_sportList.value = result
_showLoading.value = false
}
}
override fun onCleared() {
job.cancel()
}
}
below my KoinNetworkModule.kt
const val BASE_URL = "https://newsapi.org/"
val netModule = module {
single {
createWebService<SportNewsInterface>(
okHttpClient = createHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = BASE_URL
)
}
}
/* 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)
}
I fixed problem by changing my code followingly.
private fun initViewModel() {
viewModel.sportList.observe(this, Observer { result ->
when (result) {
is Results.Success -> {
val newList = result.data
if (newList != null) {
topHeadlinesAdapter.updateData(newList)
}
binding.recyclerView.adapter = topHeadlinesAdapter
topHeadlinesAdapter.notifyDataSetChanged()
}
}
})
viewModel.showLoading.observe(this, Observer { showLoading ->
pb.visibility = if (showLoading) View.VISIBLE else View.GONE
})
viewModel.loadNews()
}
Got your Problem. If you seriously want to show the response, whatever you are getting use this code in the Retrofit Instance. The role of Intercepter is used to show the request and response at the Log level. You can findout the URL of API, Request and resonse in the Log window.
Now modify KoinNetworkModule.kt like this
const val BASE_URL = "https://newsapi.org/"
val netModule = module {
single {
createWebService<SportNewsInterface>(
okHttpClient = createHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = BASE_URL
)
}
}
/* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
fun createHttpClient(): OkHttpClient {
val interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
val client1 = OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.writeTimeout(2, TimeUnit.MINUTES) // write timeout
.readTimeout(2, TimeUnit.MINUTES) // read timeout
.addInterceptor(interceptor)
.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(client1)
.build()
return retrofit.create(T::class.java)
}

how to use coroutines with retrofit in MVVM architecture

I work on a project with retrofit and rxjava in MVVM architecture that contains a repository and repositoryImpl package. I want to remove rxjava and just use Kotlin coroutine for this project.
but after search and read articles for migrating from rxjava to coroutine I did not found a right and clean way. may please help me to implement this section that implemented with rxjava implement with coroutines
MyProjectService.kt:
#POST("/user/login")
fun login(#Body agentModel: AgentModel): Observable<APIResultModel<AgentModel>>
Repository.kt :
interface Repository {
fun login(
context: Context,
userModel: AgentModel,
callback: (Result<APIResultModel<AgentModel>, RaakebException>) -> Unit
RepositoryImpl.kt :
class RepositoryImpl : Repository {
private val api = RaakebApi.instance
private val prefs by lazy {
UserPreferences()
}
override fun login(
context: Context,
userModel: AgentModel,
callback: (Result<APIResultModel<AgentModel>, RaakebException>) -> Unit
) {
val error = showError(callback)
val result = Consumer<APIResultModel<AgentModel>> { agent ->
prefs.token = agent.apiObjects.token.toString()
callback(Result.Success(agent))
}
val hashMap = HashMap<String, Any>()
val deviceModel = DeviceModel()
deviceModel.uniqueID = DeviceInfoHelper.getDeviceUniqueID(context)
deviceModel.appVersion = DeviceInfoHelper.getAppVersion()
deviceModel.platform = "ANDROID"
deviceModel.sdkVersion = DeviceInfoHelper.getSDKVersion()
deviceModel.phoneBrand = DeviceInfoHelper.getPhoneBrand()
deviceModel.phoneModel = DeviceInfoHelper.getPhoneModel()
//deviceModel.notificationID = Rakeeb.prefs.notification_id
hashMap["user"] = userModel
hashMap["device"] = deviceModel
api.login(userModel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result, error)
}
I tried to make it but It's wrong. and I don't know how I must fix it.
MyProjectService.kt :
interface MyProjectService {
#POST("/user/login")
suspend fun login(#Body agentModel: AgentModel): Result<APIResultModel<AgentModel>, RaakebException>
companion object {
private val prefs by lazy {
UserPreferences()
}
val instance: RaakebApi by lazy {
val builder = OkHttpClient.Builder()
builder.addInterceptor {
val requestBuilder = it.request().newBuilder()
if (!it.request().url().url().path?.contains("/user/login")!!) {
requestBuilder.addHeader("auth", prefs.token)
}
requestBuilder.addHeader("Content-Type", "application/json")
it.proceed(requestBuilder.build())
}
builder.readTimeout(30, TimeUnit.SECONDS)
builder.connectTimeout(30, TimeUnit.SECONDS)
val client = builder.build()
val retrofitBuilder: Retrofit.Builder = Retrofit.Builder()
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
return#lazy retrofitBuilder.baseUrl(ConstHelper.SERVER_URL)
.addConverterFactory(GsonConverterFactory.create()).build()
.create(RaakebApi::class.java)
}
}
}
Repository.kt :
interface Repository {
suspend fun login(
context: Context,
userModel: AgentModel
) : Result<APIResultModel<AgentModel>, RaakebException>
companion object {
val instance: Repository by lazy {
RepositoryImpl()
}
}
RepositoryImpl.kt :
class RepositoryImpl : Repository {
private val api = RaakebApi.instance
private val prefs by lazy {
UserPreferences()
}
override suspend fun login(
context: Context,
userModel: AgentModel
): Result<APIResultModel<AgentModel>, RaakebException> = withContext(Dispatchers.IO) {
when (val response = api.login(userModel)) {
is Result.Success -> {
/* val hashMap = HashMap<String, Any>()
val deviceModel = DeviceModel()
deviceModel.uniqueID = DeviceInfoHelper.getDeviceUniqueID(context)
deviceModel.appVersion = DeviceInfoHelper.getAppVersion()
deviceModel.platform = "ANDROID"
deviceModel.sdkVersion = DeviceInfoHelper.getSDKVersion()
deviceModel.phoneBrand = DeviceInfoHelper.getPhoneBrand()
deviceModel.phoneModel = DeviceInfoHelper.getPhoneModel()
//deviceModel.notificationID = Rakeeb.prefs.notification_id
hashMap["user"] = userModel
hashMap["device"] = deviceModel*/
return#withContext response.success
}
is Result.Error -> {
}
}
}
thanks for your help.
You can return from a retrofit api function your type with "suspend" keyword. If you want to remove rx Observables from repositories. But you need to remember: "coroutine = Single". You can't use it like Flowable. If you want I can share my project for you. I've changed rx to coroutines there.

How pass to module of Dagger parameter action: (() -> Unit) for repeat request after lost connection

I want check internet connection use ConnectivityInterceptor and passed parameter action: (() -> Unit) to module of dagger(NetworkModule) for repeat call request after connection was lost, how can I do it?
#Module
class NetworkModule {
private fun getOkHttpClient(context: Context, action: (() -> Unit)): OkHttpClient {
return OkHttpClient.Builder()
.hostnameVerifier { s, sslSession -> true }
.connectTimeout(TIME.toLong(), TimeUnit.SECONDS)
.readTimeout(TIME.toLong(), TimeUnit.SECONDS)
.writeTimeout(TIME.toLong(), TimeUnit.SECONDS)
.addInterceptor(HttpLoggingInterceptor().setLevel(if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE))
.addInterceptor(ConnectivityInterceptor(context, action))
.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
val token = BEARER + UserStorage.getInstance().token
val uuid = UserStorage.getInstance().uuid
val userAgent = Build.MANUFACTURER + " / " + Build.MODEL + " / " + Build.VERSION.RELEASE + " / " + VERSION_NAME + " / Android"
if (!TextUtils.isEmpty(UserStorage.getInstance().token)) {
requestBuilder.header(AUTHORIZATION, token)
}
if (!TextUtils.isEmpty(UserStorage.getInstance().uuid)) {
requestBuilder.header(X_UUID, UserStorage.getInstance().uuid)
}
requestBuilder.header(USER_AGENT, userAgent)
requestBuilder
.header("Accept", "application/json")
.method(original.method(), original.body())
chain.proceed(requestBuilder.build())
}
.retryOnConnectionFailure(true)
.build()
}
#Provides
#Singleton
fun provideRetrofit(gson: Gson, context: Context, action: (() -> Unit)): Retrofit {
return Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create()) // this line cut quotes
.addConverterFactory(GsonConverterFactory.create(gson))
.client(getOkHttpClient(context, action))
.baseUrl(BASE_URL)
.build()
} ...
my ConnectivityInterceptor :
class ConnectivityInterceptor(private val context: Context, private val action: (() -> Unit)): Interceptor {
#Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
if (!isNetworkAvailable(context)) {
showErrorScreen(context, action, ERROR_CLIENT)
}
val builder = chain.request().newBuilder()
return chain.proceed(builder.build())
}
}
my AppModule :
#Module
class AppModule(private val app: App) {
#Provides
#Singleton
fun provideContext(): Context = app
#Provides
fun provideApplication(): Application = app
#Provides
#Singleton
fun providesGson(): Gson =
GsonBuilder()
.serializeNulls()
.setLenient()
.registerTypeAdapterFactory(ArrayAdapterFactory())
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create()
}
my service :
interface ApiService {
#GET(VERSION)
fun getVersion(): Observable<VersionResponse>
#GET(DICTIONARIES)
fun getDictionaries(): Observable<JsonObject>
...
also
class NetworkManager #Inject constructor(private val api: ApiVideo) {
fun getVersion(): Observable<VersionResponse> {
return api.getVersion()
}
fun getDictionaries(): Observable<JsonObject> {
return api.getDictionaries()
} ...
and for example - my presenter :
class SplashPresenter #Inject constructor(): SplashContract.Presenter {
#Inject
lateinit var apiManager: NetworkManager
private var compositeDisposable = CompositeDisposable()
var view: SplashContract.View? = null
override fun detachView(view: SplashContract.View) {
this.view = null
}
override fun attachView(view: SplashContract.View) {
this.view = view
}
override fun destroy() {
compositeDisposable.clear()
}
override fun getDictionaries(context: Context) {
view?.let {
apiManager.getDictionaries()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe({ result ->
LocalizationData.getInstance(context).saveData(result)
view?.showOrHideProgressBar(false)
view?.goNextScreen()
}, { error ->
handleAnyError(view!!, error, context) { getDictionaries(context) }
}).addToCompositeDisposable(compositeDisposable)
}
}
override fun getVersion(context: Context) {
view?.let {
apiManager.getVersion()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe({ result ->
view?.showOrHideProgressBar(false)
view?.showResultVersion(result)
}, { error ->
handleAnyError(view!!, error, context) { getVersion(context) }
}).addToCompositeDisposable(compositeDisposable)
}
}
}
I think Dagger doesn't support anonymous lambdas.
Create normal named class by deriving from Kotlin lambda
class LostConnectivityAction : () -> Unit {
override fun invoke() {
// do something
}
}
you can #Provide this class in Dagger Module like any other class.

Categories

Resources