Jeremiah Jeremiah - 6 months ago 24
Android Question

converting method to Observable, still uses main thread

I am moving a pinging function to an observable so that it can be used with RxJava. It seems the call is still on the main thread and locking up the ui. Thoughts on what needs to be done to improve, did i even convert it correctly? I think it may be because of the new Handler(Looper.getMainLooper()).post(task);

public Observable<Boolean> isReachable(final String host, final int maxPings) {

return Observable.create((Subscriber<? super Boolean> subscriber) -> {

Runnable task = new Runnable() {
@Override
public void run() {
Runtime runtime = Runtime.getRuntime();
try
{
for (int i=0; i < maxPings; i++) {
Process ipAddrProcess = runtime.exec("/system/bin/ping -c 1 " + host);
int exitValue = ipAddrProcess.waitFor();
if (exitValue == 0) {
subscriber.onNext(Boolean.TRUE);
subscriber.onCompleted();
return;
}
}

subscriber.onNext(Boolean.FALSE);
subscriber.onCompleted();
return;
}
catch (InterruptedException ignore)
{
ignore.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
};
new Handler(Looper.getMainLooper()).post(task);

});
}


calling it like so

UtilsManager.getInstance().isReachable(Constants.SomeAddress, Constants.MaxPings)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
(reachable) -> {
Log.d(TAG, "Is it Reachable:" + reachable);
},
(error) -> {
Log.d(TAG, "Got Error:" + error.getMessage());

},
() -> {
Log.d(TAG,"Completed Reachable");
}
);

krp krp
Answer

subscribeOn(Schedulers.io()) specifies on which thread onSubscribe method will be called, which in your case is the whole part in Observable.create() method. However, you're posting your Runnable on main looper anyway - new Handler(Looper.getMainLooper()).post(task); . So the task posting is done on one of Schedulers.io thread, but the Runnable itself is processed on Main Thread via Main Looper. I suggest removing posting part and Runnable, just keep the body of runnable