将方法转换为 Observable,仍然使用主线程
converting method to Observable, still uses main thread
我正在将一个 ping 函数移动到一个可观察对象,以便它可以与 RxJava 一起使用。似乎调用仍在主线程上并锁定 ui。关于需要做些什么来改进的想法,我什至正确转换了吗?我认为这可能是因为 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);
});
}
这样称呼它
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");
}
);
subscribeOn(Schedulers.io())
指定在哪个线程上调用 onSubscribe 方法,在您的情况下是 Observable.create( ) 方法。但是,无论如何,您都会在主循环器上发布 Runnable - new Handler(Looper.getMainLooper()).post(task);
。因此,任务发布是在 Schedulers.io 线程之一上完成的,但 Runnable 本身是通过 Main Looper 在主线程上处理的。
我建议删除发布部分和 Runnable,只保留 runnable
的正文
我能够通过以这种方式创建 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();
}
}
});
}
我正在将一个 ping 函数移动到一个可观察对象,以便它可以与 RxJava 一起使用。似乎调用仍在主线程上并锁定 ui。关于需要做些什么来改进的想法,我什至正确转换了吗?我认为这可能是因为 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);
});
}
这样称呼它
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");
}
);
subscribeOn(Schedulers.io())
指定在哪个线程上调用 onSubscribe 方法,在您的情况下是 Observable.create( ) 方法。但是,无论如何,您都会在主循环器上发布 Runnable - new Handler(Looper.getMainLooper()).post(task);
。因此,任务发布是在 Schedulers.io 线程之一上完成的,但 Runnable 本身是通过 Main Looper 在主线程上处理的。
我建议删除发布部分和 Runnable,只保留 runnable
我能够通过以这种方式创建 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();
}
}
});
}