问题
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