使用RxJava2 zip运算符时android.os.NetworkOnMainThreadException

时间:2017-02-27 14:58:29

标签: android rx-java rx-java2

我在使用zip运算符组合多个observable时面临android.os.NetworkOnMainThreadException。据我所知,我正在使用适当的调度程序。

public void loadFeeds(final String... urls) {
    final List<Observable<Response>> observables = new ArrayList<>();
    for (String url : urls) {
        try {
            observables.add(Observable.just(RssParser.parse(url)));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    Observable<List<RSS>> rssListObservable = Observable.zip(observables, new Function<Object[], List<RSS>>() {
        public List<RSS> apply(Object[] objects) throws Exception {
            final List<RSS> rssList = new ArrayList<RSS>();

            for (Object object : objects) {
                Response response = (Response) object;
                RSS rss = new Persister().read(RSS.class, response.body().string());
                rssList.add(rss);
            }
            return rssList;
        }
    })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());

    disposable = rssListObservable.subscribeWith(new DisposableObserver<List<RSS>>() {
        @Override
        public void onNext(List<RSS> rssList) {
            //rssCallback.rssFeedsLoaded(rssList);
            Log.d(TAG, "onNext: rssListSize: "+rssList.size());
        }

        @Override
        public void onError(Throwable e) {
            Log.e(TAG, "onError: " + e.getMessage(), e);
        }

        @Override
        public void onComplete() {
            Log.d(TAG, "onComplete: done");
        }
    });
}

我正在使用Observable.just()

将此方法转换为observable
static Response parse(String feedUrl) throws IOException {
    Request request = new Request.Builder()
            .url(feedUrl)
            .get()
            .build();

    return OK_HTTP_CLIENT.newCall(request).execute();
}

以下是错误日志:

FATAL EXCEPTION: main
Process: com.crazyhitty.chdev.ks.rssmanagerlib, PID: 18980
android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:86)
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
    at java.net.InetAddress.getAllByName(InetAddress.java:752)
    at okhttp3.Dns$1.lookup(Dns.java:39)
    at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:170)
    at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:136)
    at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:81)
    at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:171)
    at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
    at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
    at okhttp3.RealCall.execute(RealCall.java:63)
    at com.crazyhitty.chdev.ks.rssmanager.RssParser.parse(RssParser.java:29)
    at com.crazyhitty.chdev.ks.rssmanager.RssReader.loadFeeds(RssReader.java:43)
    at com.crazyhitty.chdev.ks.rssmanagerlib.MainActivity.loadFeeds(MainActivity.java:72)
    at com.crazyhitty.chdev.ks.rssmanagerlib.MainActivity.access$200(MainActivity.java:21)
    at com.crazyhitty.chdev.ks.rssmanagerlib.MainActivity$1.onClick(MainActivity.java:54)
    at android.view.View.performClick(View.java:5637)
    at android.view.View$PerformClick.run(View.java:22429)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6119)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

感谢任何形式的帮助或指导,谢谢:)

编辑:找到解决方案的人,基本上作为一个RxJava新手,我不知道Observable.just()立即执行当前线程上的observable。因此,不应使用Observable.just(),而应在此类场景中使用Observable.create()。

固定代码:

public void loadFeeds(final String... urls) {
    final long startTimeMillis=System.currentTimeMillis();

    final List<Observable<RSS>> observables = new ArrayList<>();
    for (final String url : urls) {
        observables.add(Observable.create(new ObservableOnSubscribe<RSS>() {
            @Override
            public void subscribe(ObservableEmitter<RSS> emitter) throws Exception {
                RSS rss = new Persister().read(RSS.class, RssParser.parse(url).body().string());
                Log.d(TAG, "subscribe: url: " + url + " ; thread: " + Thread.currentThread().getName());
                emitter.onNext(rss);
                emitter.onComplete();
            }
        }));
    }

    Observable<List<RSS>> rssListObservable = Observable.zip(observables, new Function<Object[], List<RSS>>() {
        @Override
        public List<RSS> apply(Object[] objects) throws Exception {
            final List<RSS> rssList = new ArrayList<RSS>();

            for (Object object : objects) {
                rssList.add((RSS) object);
            }

            return rssList;
        }
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());

    disposable = rssListObservable.subscribeWith(new DisposableObserver<List<RSS>>() {
        @Override
        public void onNext(List<RSS> rssList) {
            rssCallback.rssFeedsLoaded(rssList);
            Log.d(TAG, "onNext: rssListSize: " + rssList.size());
        }

        @Override
        public void onError(Throwable e) {
            rssCallback.unableToReadRssFeeds(e.getMessage());
            Log.e(TAG, "onError: " + e.getMessage(), e);
        }

        @Override
        public void onComplete() {
            Log.d(TAG, String.format(Locale.ENGLISH, "onComplete: done with time spent(ms): %d", (System.currentTimeMillis()-startTimeMillis)));
        }
    });
}

0 个答案:

没有答案