将方法转换为Observable,仍然使用主线程

时间:2016-05-19 19:33:05

标签: android multithreading rx-java rx-android

我正在将一个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");
                    }
            );

2 个答案:

答案 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来修复它,发布到m​​ainlooper是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();
            }

        }
    });
}