2017-04-19 78 views
-1

我有時會得到異常 - android.os.NetworkOnMainThreadException,有時代碼的作品。Android rxjava與okhttp - NetworkOnMainThreadException

這裏是我的代碼

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) { ... 

有時候結果是:

11月4日至19日:34:21.890 9763-9763 /? W/System.err:android.os.NetworkOnMainThreadException 04-19 11:34:21.890 9763-9763 /? W/System.err:在android.os.StrictMode $ AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273) 04-19 11:34:21.890 9763-9763 /? W/System.err:在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:在java.net.PlainSocketImpl.read(PlainSocketImpl.java:481) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.net.PlainSocketImpl.access $ 000(PlainSocketImpl.java:37) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.net.PlainSocketImpl $ PlainSocketInputStream.read(PlainSocketImpl.java:237) 04-19 11:34:21.890 9763-9763 /? W/System.err:在okio.Okio $ 2.read(Okio.java:138) 04-19 11:34:21.890 9763-9763 /? W/System.err:在okio.AsyncTimeout $ 2.read(AsyncTimeout.java:238) 04-19 11:34:21.890 9763-9763 /? W/System.err:在okio.RealBufferedSource.read(RealBufferedSource.java:45) 04-19 11:34:21.890 9763-9763 /? W/System.err:在okhttp3.internal.http.Http1xStream $ FixedLengthSource.read(Http1xStream.java:377) 04-19 11:34:21.890 9763-9763 /? W/System.err:在okio.RealBufferedSource.read(RealBufferedSource.java:45) 04-19 11:34:21.890 9763-9763 /? W/System.err:在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:在okio.GzipSource.read(GzipSource.java:80) 04-19 11:34:21.890 9763-9763 /? W/System.err:在okio.RealBufferedSource $ 1.read(RealBufferedSource.java:409) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.io.InputStreamReader.read(InputStreamReader.java:233) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.io.Reader.read(Reader.java:141) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.io.Reader.read(Reader.java:245) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.util.Scanner.readMore(Scanner.java:2068) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.util.Scanner.findDelimiterAfter(Scanner.java:2038) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.util.Scanner.setTokenRegion(Scanner.java:1953) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.util.Scanner.next(Scanner.java:965) 04-19 11:34:21.890 9763-9763 /? W/System.err:在java.util.Scanner.next(Scanner.java:941) 04-19 11:34:21.890 9763-9763 /? W/System.err:在uz.newsign.mvp.ImplPresenter $ 3.call(ImplPresenter.java:121) 04-19 11:34:21.891 9763-9763 /? W/System.err:在uz.newsign.mvp.ImplPresenter $ 3.call(ImplPresenter.java:115) 04-19 11:34:21.891 9763-9763 /? W/System.err:在rx.internal.operators.OperatorMap $ MapSubscriber.onNext(OperatorMap.java:66) 04-19 11:34:21.891 9763-9763 /? W/System.err:在rx.internal.operators.OperatorUnsubscribeOn $ 1.onNext(OperatorUnsubscribeOn.java:53) 04-19 11:34:21.891 9763-9763 /? W/System.err:在rx.internal.operators.OperatorObserveOn $ ObserveOnSubscriber.call(OperatorObserveOn。java:227) 04-19 11:34:21.891 9763-9763 /? W/System.err:在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:在android.os.Looper.loop(Looper.java:148) 04-19 11:34:21.891 9763-9763 /? W/System.err:在android.app.ActivityThread.main(ActivityThread.java:5441) 04-19 11:34:21.891 9763-9763 /? W/System.err:在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:引起:rx.exceptions.OnErrorThrowable $ OnNextValue:OnError發出onNext值:okhttp3.Response.class 04-19 11:34:21.891 9763-9763 /? W/System.err:在rx.internal.operators.OperatorMap $ MapSubscriber.onNext(OperatorMap.java:70) 04-19 11:34:21.891 9763-9763 /? W/System.err:...更多

我在做什麼錯了?或者它的錯誤?

回答

0

你不能在主線程上進行網絡調用。因此,對於網絡,你應該使用工作線程在後臺調用網絡調用,完成工作後,只需獲得響應併發布UI。

+0

.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - 它是你的答案? –

-1

發生這種情況是因爲您在進行實際工作的同一範圍內(主線程)發出網絡請求。如果網絡請求在主線程上完成,那麼您的主代碼將被網絡請求阻止,直到收到響應,這將導致應用程序出現意外行爲。在處理網絡請求時,建議您在其他線程上發出網絡請求。你可以通過AsyncTask來完成。 更多的信息:https://developer.android.com/reference/android/os/AsyncTask.html

或者,您也可以使用谷歌的Volley庫來處理線程問題。 這裏更多的信息:https://developer.android.com/training/volley/index.html

+0

他正在與Rxjava合作,所以不需要異步任務或排隊 –

+0

謝謝。但之前我與asynctask合作,但現在我刪除了所有舊的代碼,現在我正在嘗試用現代rxjava,rxandroid與okhttp編寫其餘api代碼,但它不能正常工作 –

0

變化Schedulers.io()Schedulers.newThread()

+0

雖然此代碼可能會回答問題,提供額外的[上下文](https://meta.stackexchange.com/q/114762)關於_how_和/或_why_它解決了這個問題會提高答案的長期價值。請記住,你正在爲將來的讀者回答這個問題,而不僅僅是現在問的人!請[編輯](http://stackoverflow.com/posts/43488977/edit)您的答案添加一個解釋,並指出適用的限制和假設。它也不會提到爲什麼這個答案比其他答案更合適。 –

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

訂閱新的線程,並觀察mainThread

0

嘗試自行創建線程池和訂閱就可以了。

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

我試過了,但不起作用 –

相關問題