Android rxjava with okhttp - NetworkOnMainThreadException

若如初见. 提交于 2019-12-12 02:32:42

问题


I sometimes get exception - android.os.NetworkOnMainThreadException, sometimes code works.

Here is my code

Observable.create(new Observable.OnSubscribe<Response>() {
        OkHttpClient client = new OkHttpClient();

        @Override
        public void call(Subscriber<? super Response> subscriber) {
            try {
                Response response = client.newCall(request).execute();

                subscriber.onNext(response);
                subscriber.onCompleted();
            } catch (IOException e) {
                subscriber.onError(e);
            }

        }
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .unsubscribeOn(Schedulers.io())
            .map(new Func1<Response, Res>() {
                @Override

                public Res call(Response response) {

                    String post = new Scanner(response.body().byteStream(), "UTF-8")
                            .useDelimiter("\\A").next();
                    Log.d(TAG,post);
                    return model.deCryptData(post);
                }
            })

            .subscribe(new Action1<Res>() {
                @Override
                public void call(Res res) { ...

Sometimes result is:

04-19 11:34:21.890 9763-9763/? W/System.err: android.os.NetworkOnMainThreadException 04-19 11:34:21.890 9763-9763/? W/System.err: at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273) 04-19 11:34:21.890 9763-9763/? W/System.err: at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:249) 04-19 11:34:21.890 9763-9763/? W/System.err: at libcore.io.IoBridge.recvfrom(IoBridge.java:549) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.net.PlainSocketImpl.read(PlainSocketImpl.java:481) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.Okio$2.read(Okio.java:138) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.AsyncTimeout$2.read(AsyncTimeout.java:238) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.RealBufferedSource.read(RealBufferedSource.java:45) 04-19 11:34:21.890 9763-9763/? W/System.err: at okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:377) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.RealBufferedSource.read(RealBufferedSource.java:45) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.RealBufferedSource.exhausted(RealBufferedSource.java:55) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.InflaterSource.refill(InflaterSource.java:101) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.InflaterSource.read(InflaterSource.java:62) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.GzipSource.read(GzipSource.java:80) 04-19 11:34:21.890 9763-9763/? W/System.err: at okio.RealBufferedSource$1.read(RealBufferedSource.java:409) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.io.InputStreamReader.read(InputStreamReader.java:233) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.io.Reader.read(Reader.java:141) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.io.Reader.read(Reader.java:245) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.util.Scanner.readMore(Scanner.java:2068) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.util.Scanner.findDelimiterAfter(Scanner.java:2038) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.util.Scanner.setTokenRegion(Scanner.java:1953) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.util.Scanner.next(Scanner.java:965) 04-19 11:34:21.890 9763-9763/? W/System.err: at java.util.Scanner.next(Scanner.java:941) 04-19 11:34:21.890 9763-9763/? W/System.err: at uz.newsign.mvp.ImplPresenter$3.call(ImplPresenter.java:121) 04-19 11:34:21.891 9763-9763/? W/System.err: at uz.newsign.mvp.ImplPresenter$3.call(ImplPresenter.java:115) 04-19 11:34:21.891 9763-9763/? W/System.err: at rx.internal.operators.OperatorMap$MapSubscriber.onNext(OperatorMap.java:66) 04-19 11:34:21.891 9763-9763/? W/System.err: at rx.internal.operators.OperatorUnsubscribeOn$1.onNext(OperatorUnsubscribeOn.java:53) 04-19 11:34:21.891 9763-9763/? W/System.err: at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:227) 04-19 11:34:21.891 9763-9763/? W/System.err: at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107) 04-19 11:34:21.891 9763-9763/? W/System.err: at android.os.Handler.handleCallback(Handler.java:739) 04-19 11:34:21.891 9763-9763/? W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95) 04-19 11:34:21.891 9763-9763/? W/System.err: at android.os.Looper.loop(Looper.java:148) 04-19 11:34:21.891 9763-9763/? W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5441) 04-19 11:34:21.891 9763-9763/? W/System.err: at java.lang.reflect.Method.invoke(Native Method) 04-19 11:34:21.891 9763-9763/? W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738) 04-19 11:34:21.891 9763-9763/? W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628) 04-19 11:34:21.891 9763-9763/? W/System.err: Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: okhttp3.Response.class 04-19 11:34:21.891 9763-9763/? W/System.err: at rx.internal.operators.OperatorMap$MapSubscriber.onNext(OperatorMap.java:70) 04-19 11:34:21.891 9763-9763/? W/System.err: ... 10 more

What I'm doing wrong? or it's bug?


回答1:


.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())

subscribe on new thread and observe on mainThread




回答2:


Try to create ThreadPool by yourself and subscribe on it.

    ExecutorService webRequestsExecutor = Executors.newFixedThreadPool(1);
    //Other stuff    
    .subscribeOn(Schedulers.from(webRequestsExecutor))
                    .observeOn(AndroidSchedulers.mainThread())
                    .unsubscribeOn(Schedulers.io())



回答3:


You can't do network call on main thread .So for network you should use worker thread for calling network call in background and after your work is done just get response and post your UI.




回答4:


Change Schedulers.io() to Schedulers.newThread()




回答5:


private Call uploadImage(Callback callback){    
    OkHttpClient client = new OkHttpClient();

    RequestBody formBody = new FormEncodingBuilder()
        .add("param_1", "1234")
        .add("param_2", "acv")
        .build();

    Request request = new Request.Builder()
        .url(URL)
        .post(formBody)
        .build();

    Call call = client.newCall(request);
    call.enqueue(callback);
    return call;        
}

uploadImage(new Callback() {
  @Override public void onResponse(final com.squareup.okhttp.Response response)  {                                      
            final String responseStr;                                               
            try {
                responseStr = response.body().string();
                HomeActivity.this.runOnUiThread(new Runnable() {
                           public void run() {
                                        //Update UI here                                                                
                                 }
                            });                                                         
                } catch (IOException e) {
                    e.printStackTrace();
                }                                                
             }
@Override
public void onFailure(Request req, IOException exp) {
    }
});



回答6:


This happens because you are making network requests in the same scope where you are doing actual work(the main thread). If network request is done on the main thread, then your main code will get blocked by the network request until a response is received which will lead to unexpected behaviour in your app. While dealing with network requests, it is recommended that you should make network requests on other thread. You can do this by AsyncTask. More info here: https://developer.android.com/reference/android/os/AsyncTask.html.

Or, alternatively you can use Volley library from Google which handles the thread issue itself. More info here: https://developer.android.com/training/volley/index.html



来源:https://stackoverflow.com/questions/43488683/android-rxjava-with-okhttp-networkonmainthreadexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!