I've tried everything and didn't get any results. I just know that subscribeOn method switches the operation to the background thread and prevent UI thread blocking and I should expect that anything happens on the background thread should not affect the user flow. Now I'm not sure that did I get the wrong info about the subscribeOn() method or do I have a bug in my code?
String profileUrl = BuildConfig.BASEURL + "pharma/patient/profile?username=" + caregiverNo;
try {
Observable.just(OkhttpClientManager.getInstance(APP_NAME, APP_VERSION).getRequest(profileUrl))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
callback.getDisposable(d);
}
@Override
public void onNext(String s) {
CaregiverUserResponse response = new Gson().fromJson(s, CaregiverUserResponse.class);
if (response.getResult().equals(Constants.API_CALL_SUCCESS)) {
updateCaregiverCache(response);
getUserData(callback, patientNo, authToken);
} else {
callback.onError(new NetworkError(new Throwable(response.getError())));
}
}
@Override
public void onError(Throwable e) {
callback.onError(new NetworkError(e));
}
@Override
public void onComplete() {
}
});
} catch (Exception e) {
Log.e(TAG, "getCaregiverProfile: ", e);
}
This is my code in which getRequest() function returns the response as String. and I'm getting this error NetworkOnMainThreadException and I know that subscribeOn(Schedulers.io()) performs the operation on the background thread.
Error:
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1565)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:389)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:621)
at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:73)
at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:246)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:166)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
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)
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)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
at okhttp3.RealCall.execute(RealCall.java:92)
at com.healthapp.myadhero.network.OkhttpClientManager.getRequest(OkhttpClientManager.java:64)
at com.healthapp.myadhero.network.Service.getCaregiverProfile(Service.java:81)
at com.healthapp.myadhero.network.Service.access$200(Service.java:68)
at com.healthapp.myadhero.network.Service$2.onNext(Service.java:154)
at com.healthapp.myadhero.network.Service$2.onNext(Service.java:131)
at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:201)
at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255)
at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:124)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Thanks in advance.
You are calling that getRequest
before RxJava is even involved, then you hand the result value to RxJava. Using just
near network call is often wrong and you should be using fromCallable
.
String profileUrl = BuildConfig.BASEURL + "pharma/patient/profile?username=" + caregiverNo;
Observable.fromCallable(() ->
OkhttpClientManager
.getInstance(APP_NAME, APP_VERSION)
.getRequest(profileUrl)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
callback.getDisposable(d);
}
@Override
public void onNext(String s) {
CaregiverUserResponse response = new Gson().fromJson(s, CaregiverUserResponse.class);
if (response.getResult().equals(Constants.API_CALL_SUCCESS)) {
updateCaregiverCache(response);
getUserData(callback, patientNo, authToken);
} else {
callback.onError(new NetworkError(new Throwable(response.getError())));
}
}
@Override
public void onError(Throwable e) {
callback.onError(new NetworkError(e));
}
@Override
public void onComplete() {
}
});