W/System.err: java.net.UnknownHostException: Unable to resolve host "api.rawg.io": No address associated with hostname
W/System.err: at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:156)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
at java.net.InetAddress.getAllByName(InetAddress.java:1152)
at okhttp3.Dns$1.lookup(Dns.java:40)
at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:185)
at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:149)
at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:84)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:214)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
at okhttp3.RealCall.execute(RealCall.java:92)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:186)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:45)
at io.reactivex.Observable.subscribe(Observable.java:10838)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:10838)
at io.reactivex.internal.operators.flowable.FlowableFromObservable.subscribeActual(FlowableFromObservable.java:29)
at io.reactivex.Flowable.subscribe(Flowable.java:12978)
at io.reactivex.internal.operators.flowable.FlowableOnBackpressureLatest.subscribeActual(FlowableOnBackpressureLatest.java:32)
at io.reactivex.Flowable.subscribe(Flowable.java:12978)
at io.reactivex.internal.operators.flowable.FlowableDoOnEach.subscribeActual(FlowableDoOnEach.java:50)
at io.reactivex.Flowable.subscribe(Flowable.java:12978)
at io.reactivex.Flowable.subscribe(Flowable.java:12924)
at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:929)
W/System.err: Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
W/System.err: at libcore.io.Linux.android_getaddrinfo(Native Method)
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:200)
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:74)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:135)
... 43 more
When application have connection with internet working good but when i have no internet connection my application crash. I want to handle this Exception but anything what i tried not helped :/ . I tried too check if source is not null . I am using Dagger 2 , Retrofit 2, RxJava, viewModel .
class VideoViewModel : ViewModel {
private val authApi: AuthApi
private val games: MediatorLiveData<TopGames> = MediatorLiveData<TopGames>()
#Inject
constructor(authApis: AuthApi) {
authApi = authApis
}
fun authenticateWithId(dates: String) {
val source: LiveData<TopGames> = LiveDataReactiveStreams.fromPublisher(
authApi.getTopGames(dates, "-added").doOnError { t-> print("${t.printStackTrace()} doOnError") }
.subscribeOn(Schedulers.io())
)
games.addSource<TopGames>(source, object : androidx.lifecycle.Observer<TopGames?> {
override fun onChanged(t: TopGames?) {
// Log.d("TAG", "VideoonChanged: $t")
games.value = t
games.removeSource(source)
}
})
}
fun observeGaneInfo(): LiveData<TopGames?>? {
return games
}
}
Other class
interface AuthApi {
#GET("/api/games")
fun getTopGames(
#Query("dates") dates: String,
#Query("ordering") ordering: String
): Flowable<TopGames>
}
There is no error handling in your rx chain. So you might to want to do something like this.
val source: LiveData<TopGames> = LiveDataReactiveStreams.fromPublisher(
authApi.getTopGames(dates, "-added")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
games.value = it
},
{
// error handling goes here
}
)
)
You can have separate LiveData for your error messages, but the more cleaner approach would be to create State class, as mentioned in other replies, so you only have the single source of view state updates.
Also please note that the Disposable return from subscribe method is better to be disposed on ViewModel's onCleared method.
Solution :
create data class on State
data class DataWithStates<T>(
val data: T? = null,
val states: Throwable? = null
)
and in my live data i change val source: LiveData to LiveData<DataWithStates> and work perfectly
fun authenticateWithId(dates: String) {
val source: LiveData<DataWithStates<TopGames>> = LiveDataReactiveStreams.fromPublisher(
authApi.getTopGames(dates, "-added").map { lstUser -> DataWithStates(lstUser) }.onErrorReturn { ex -> DataWithStates(states = ex) }
.subscribeOn(Schedulers.io())
)
games.addSource<DataWithStates<TopGames>>(source, object : androidx.lifecycle.Observer<DataWithStates<TopGames>> {
override fun onChanged(t: DataWithStates<TopGames>) {
// Log.d("TAG", "VideoonChanged: $t")
games.value = t.data
games.removeSource(source)
}
})
}
helpful Link
RxJava to live data error Handling
Related
My app has a specific requirement of uploading files as multipart using retrofit and LiveData in the background(App Navigation works while uploading data to the server.). The app requires chained network requests on the bases of the response it gets. I've used the Foreground service for network requests. this procedure works well in Android 9,10,11.
UploadFragment.kt
class UploadFragment : BaseFragment() {
....
private fun uploadFilesToServer() {
val intent = Intent(requireActivity(), MyFileUploadingService::class.java)
ContextCompat.startForegroundService(requireActivity(), intent)
}
}
FileUploadService.kt
class FileUploadService : LifecycleService() {
....
private fun registerObservers() {
viewModel?.uploadLiveData!!.observe(this) { response ->
val dataResponse: DataUploadResponse = response.responseBody!!.data!!
if (dataResponse.error == null) {
....
// Repeat
} else {
stopSelf()
}
}
}
}
I'm getting an error while observing response using LiveData.
val dataResponse: DataUploadResponse = response.responseBody!!.data!!
Error Log
2022-08-24 13:08:59.792 26140-26140/com.myapp.demo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.demo, PID: 26140
java.lang.NullPointerException
at com.myapp.demo.service.FileUploadService$registerObservers$1.onChanged(FileUploadService.kt:242)
at com.myapp.demo.service.FileUploadService$registerObservers$1.onChanged(FileUploadService.kt:54)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
at androidx.lifecycle.LiveData$1.run(LiveData.java:93)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7870)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
I am trying to integrate Kommunicate Chatbot in my Android App.
After I have created KMUser with UserId and trying to login using Kommunicate.login(), it is giving me IllegalArgumentException, in onFailure() function.
This exception only occurs in release build, but not in debug build.
I have tried switching data in KMUser but didn't help.
Here is the code snippet.
Kommunicate.init(this#HomeActivity, APP_ID)
if (!(mHomeViewModel?.dbProfileResponseModel?.contactNum.isNullOrEmpty())) {
kmUser.userId = mHomeViewModel?.dbProfileResponseModel?.contactNum
} else {
kmUser = Kommunicate.getVisitor()
}
if (!(mHomeViewModel?.dbProfileResponseModel?.email.isNullOrEmpty())) {
kmUser.email = mHomeViewModel?.dbProfileResponseModel?.email
}
kmUser.applicationId = APP_ID
Kommunicate.login(this#HomeActivity, kmUser, object : KMLoginHandler {
override fun onSuccess(registrationResponse: RegistrationResponse?, context: Context?) {
val botIds = arrayListOf<String>()
botIds.add("beekun-yx526")
KmConversationBuilder(this#HomeActivity)
.setSingleConversation(false)
.setBotIds(botIds)
.setKmUser(kmUser)
.launchConversation(object : KmCallback {
override fun onSuccess(message: Any) {
progressDialog.dismiss()
}
override fun onFailure(error: Any) {
progressDialog.dismiss()
}
})
}
override fun onFailure(registrationResponse: RegistrationResponse?, exception: Exception?) {
if (progressDialog != null && progressDialog.isShowing) {
progressDialog.dismiss()
}
createLoginErrorDialog(registrationResponse, exception)
}
})
This is the exception raised.
W/System.err: java.lang.IllegalArgumentException: class c.b.g.a declares multiple JSON fields named a
W/System.err: at com.google.gson.b.a.i.a(ReflectiveTypeAdapterFactory.java:172)
W/System.err: at com.google.gson.b.a.i.a(ReflectiveTypeAdapterFactory.java:102)
W/System.err: at com.google.gson.Gson.a(Gson.java:458)
W/System.err: at com.google.gson.Gson.a(Gson.java:696)
W/System.err: at com.google.gson.Gson.a(Gson.java:683)
W/System.err: at com.google.gson.Gson.b(Gson.java:638)
W/System.err: at com.google.gson.Gson.b(Gson.java:618)
W/System.err: at com.applozic.mobicomkit.api.a.a.a.a(RegisterUserClientService.java:100)
W/System.err: at c.b.a.i.a(KmUserLoginTask.java:62)
W/System.err: at c.b.a.i.doInBackground(KmUserLoginTask.java:24)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:334)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:246)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
W/System.err: at java.lang.Thread.run(Thread.java:764)
Please help me out resolving this issue.
This is not the issue with build flavor, you might have enabled proguard for release build and haven't added their proguard rules in your proguard-rules.pro file.
Checkout the doc to add the rules in your proguard file: https://docs.kommunicate.io/docs/android-installation#building-with-proguard
I need to get data from Api for each list element also I need to implement Internet connection checker.
Then program starts everything works great.
I disable Internet on live, and run method again (using swipeRefreshLayout), I receive InternetErrorToast, great!
I restored Internet on live, and run method again (using swipeRefreshLayout), app crashed with error.
Now I have following method.
Note! dataManager.getCityConditionsResponse() return Single
#Override
public void updateCitiesList() {
List<City> citiesList = dataManager.getCitiesFromDb();
if (!dataManager.isInternetConnected()) {
view.showCitiesList(citiesList);
view.showInternetErrorToast();
} else {
compositeDisposable.add(Observable.fromIterable(citiesList)
.doOnNext(city -> dataManager.getCityConditionsResponse(city.getQuery())
.subscribe(
response -> {
city.setTemp(response.getTemp());
city.setIcon(response.getIcon());
},
error -> view.showServerErrorToast()))
.toList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
list -> view.showCitiesList(list),
error -> view.showServerErrorToast()
));
}
view.hideRefreshingStatus();
}
On step 3 I have this error
018-10-12 16:34:54.033 19013-19046/mike.weather E/AndroidRuntime: FATAL EXCEPTION: RxCachedThreadScheduler-1
Process: mike.weather, PID: 19013
io.reactivex.exceptions.CompositeException: 2 exceptions occurred.
at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:49)
at io.reactivex.internal.operators.observable.ObservableSingleSingle$SingleElementObserver.onError(ObservableSingleSingle.java:93)
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onError(BodyObservable.java:72)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:56)
at io.reactivex.Observable.subscribe(Observable.java:12090)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:12090)
at io.reactivex.internal.operators.observable.ObservableSingleSingle.subscribeActual(ObservableSingleSingle.java:35)
at io.reactivex.Single.subscribe(Single.java:3438)
at io.reactivex.Single.subscribe(Single.java:3424)
at mike.weather.ui.main.MainActivityPresenter.lambda$updateCitiesList$3(MainActivityPresenter.java:49)
at mike.weather.ui.main.-$$Lambda$MainActivityPresenter$UqLPaAef0SB9PT-Rz654tgX3dnA.accept(Unknown Source:4)
at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onNext(ObservableDoOnEach.java:93)
at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.onNext(ObservableDoOnEach.java:101)
at io.reactivex.internal.operators.observable.ObservableFromIterable$FromIterableDisposable.run(ObservableFromIterable.java:98)
at io.reactivex.internal.operators.observable.ObservableFromIterable.subscribeActual(ObservableFromIterable.java:58)
at io.reactivex.Observable.subscribe(Observable.java:12090)
at io.reactivex.internal.operators.observable.ObservableDoOnEach.subscribeActual(ObservableDoOnEach.java:42)
at io.reactivex.Observable.subscribe(Observable.java:12090)
at io.reactivex.internal.operators.observable.ObservableDoOnEach.subscribeActual(ObservableDoOnEach.java:42)
at io.reactivex.Observable.subscribe(Observable.java:12090)
at io.reactivex.internal.operators.observable.ObservableToListSingle.subscribeActual(ObservableToListSingle.java:58)
at io.reactivex.Single.subscribe(Single.java:3438)
at io.reactivex.internal.operators.single.SingleDoOnSuccess.subscribeActual(SingleDoOnSuccess.java:35)
at io.reactivex.Single.subscribe(Single.java:3438)
at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
........................
It would be more Rx idiomatic if you rewrite your observable like that
compositeDisposable.add(Observable.fromArray(citiesList)
.flatMap(Observable::fromIterable)
.flatMapSingle(city ->
dataManager.getCityConditionsResponse(city.getQuery())
.map(response -> {
city.setTemp(response.getTemp());
city.setIcon(response.getIcon());
return city;
})
)
.toList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
list -> view.showCitiesList(list),
error -> view.showServerErrorToast()
));
After that I think you problem will disappear.
I'm trying to handle errors in Rx android networking but unable to do so can some help.
getCompositeDisposable().add(getManager().callApi(request)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.ui())
.subscribe(apiResponse -> Log.d(TAG,"success"),
throwable -> Log.e(TAG,throwable.getMessage)));
I want to handle errors in subscribe()
Logs:
io.reactivex.exceptions.OnErrorNotImplementedException: java.net.ConnectException: Failed to connect
at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:47)
at io.reactivex.internal.operators.single.SingleObserveOn$ObserveOnSingleObserver.run(SingleObserveOn.java:79)
at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7231)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: com.androidnetworking.error.ANError: java.net.ConnectException: Failed to connect to /192.168.1.42:8484
at com.rx2androidnetworking.Rx2InternalNetworking$SimpleANObservable.subscribeActual(Rx2InternalNetworking.java:235)
at io.reactivex.Observable.subscribe(Observable.java:10981)
at io.reactivex.internal.operators.observable.ObservableSingleSingle.subscribeActual(ObservableSingleSingle.java:35)
at io.reactivex.Single.subscribe(Single.java:2801)
at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
Unfortunately i can not comment. Could you be more specific? What error have you got? The common way to handle errors using rx looks like this:
Subscription subscribe = apiServices.endpointCall(...parameters...)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.unsubscribeOn(Schedulers.io());
.subscribe(response -> {
//do something with response
}, throwable -> {
//do something with error
});
Where apiService is created by retrofit using
service = retrofit.create(ApiServices.class);
At first, I know that network operations shouldn`t be called from Main thread. Thats why I am observing completables on Schedulers.io()!
I am trying to concat two completable. Both completable use network, thats why i subscribe on Schedulers.io(). If i am using concatWith(or andThen) code fails with NetworkOnMainThreadException. Here is kotlin code:
val singleSubject = SingleSubject.create<String>();
completalbe1.concatWith(completable2)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe({
singleSubject.onSuccess("ok")
}, { error ->
Log.e(tag, error.message, error)//here i got exception
singleSubject.onError(error)
})
return singleSubject
If i rewrite code without completable chaining - all is ok. Here is working code:
val singleSubject = SingleSubject.create<String>();
completable1
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe({
completable2
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe({
singleSubject.onSuccess("ok")
}, { error ->
Log.e(tag, error.message, error)
singleSubject.onError(error)
})
}, {error ->
Log.e(tag, error.message, error)
singleSubject.onError(error)
})
return singleSubject
I wonder why first snippet don`t work but second does?
UPD1:Here is stacktrace:
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:249)
at libcore.io.IoBridge.recvfrom(IoBridge.java:549)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:481)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at okio.Okio$2.read(Okio.java:139)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:237)
at okio.RealBufferedSource.exhausted(RealBufferedSource.java:56)
at okhttp3.internal.connection.RealConnection.isHealthy(RealConnection.java:498)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:133)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:211)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
at okhttp3.RealCall.execute(RealCall.java:69)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
at com.jakewharton.retrofit2.adapter.rxjava2.CallObservable.subscribeActual(CallObservable.java:41)
at io.reactivex.Observable.subscribe(Observable.java:10955)
at com.jakewharton.retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:10955)
at io.reactivex.internal.operators.observable.ObservableIgnoreElementsCompletable.subscribeActual(ObservableIgnoreElementsCompletable.java:31)
at io.reactivex.Completable.subscribe(Completable.java:1664)
at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.next(CompletableConcatArray.java:89)
at io.reactivex.internal.operators.completable.CompletableConcatArray$ConcatInnerObserver.onComplete(CompletableConcatArray.java:65)
at io.reactivex.internal.operators.completable.CompletableCreate$Emitter.onComplete(CompletableCreate.java:64)
at com.catalyst.opti.AppManager$transferImage$1$subscribe$1.onStateChanged(AppManager.kt:323)
at com.amazonaws.mobileconnectors.s3.transferutility.TransferStatusUpdater$1.run(TransferStatusUpdater.java:172)
at android.os.Handler.handleCallback(Handler.java:742)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:5527)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
UPD2:
completable1 is a function uploading file to AWS S3:
private fun transferImage(imageName: String, image: File): Completable {
return Completable.create(object : CompletableOnSubscribe {
override fun subscribe(e: CompletableEmitter) {
val transferObserver = transferUtility.upload("some", imageName, image)
transferObserver.setTransferListener(object : TransferListener {
override fun onProgressChanged(id: Int, bytesCurrent: Long, bytesTotal: Long) {
Log.i(tag, "bytesCurrent: $bytesCurrent, bytesTotal: $bytesTotal")
}
override fun onStateChanged(id: Int, state: TransferState?) {
if (state == TransferState.COMPLETED) {
e.onComplete()
}
}
override fun onError(id: Int, ex: java.lang.Exception) {
Log.d(tag, "error transfer s3: ${ex.message}", ex)
e.onError(ex)
}
})
}
});
}
completable2 is retrofit2 call:
#POST("some")
fun verifyLocation(#Header(AUTH_TOKEN_HEADER) authToken: String, #Body
verifyLocation: VerifyLocation): Completable
I'd guess transferObserver.setTransferListener calls the callback on the main thread which then will subscribe to completable2 on the main thread as well. You have to apply subscribeOn(Schedulers.io()) to completable2, just like in your other example.
val singleSubject = SingleSubject.create<String>();
completalbe1.subscribeOn(Schedulers.io())
.concatWith(completable2.subscribeOn(Schedulers.io())) // <-----------------------
.observeOn(Schedulers.io())
.subscribe({
singleSubject.onSuccess("ok")
}, { error ->
Log.e(tag, error.message, error)//here i got exception
singleSubject.onError(error)
})
return singleSubject
subscribeOn affects subscription (side) effects but your completalbe1 has an observation effect when it calls onComplete on the main thread.