我正在将一个pinging函数移动到一个observable,以便它可以与RxJava一起使用。似乎调用仍在主线程上并锁定了ui。关于需要做些什么改进的想法,我甚至正确地将其转换了吗?我想这可能是因为新的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);
});
}
称之为
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");
}
);
答案 0 :(得分:1)
subscribeOn(Schedulers.io())
指定将调用 onSubscribe 方法的线程,在您的情况下,它是 Observable.create()方法的整个部分。但是,您仍然会在主要循环播放器上发布 Runnable - new Handler(Looper.getMainLooper()).post(task);
。因此,任务发布是在Schedulers.io线程之一上完成的,但Runnable本身是通过Main Looper在主线程上处理的。
我建议删除发布部分和Runnable,只保留runnable的主体
答案 1 :(得分:0)
我能够通过这种方式创建Observable来修复它,发布到mainlooper是krp提到的原因:
public Observable<Boolean> isReachable(final String host, final int maxPings) {
return Observable.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
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();
}
}
});
}