将方法转换为 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();
            }

        }
    });
}