android.os.NetworkOnMainThreadException在Android上使用rxjava

我有麻烦实施rxJava为了检查是否有互联网连接在Android上我这样做是这样的:

在我的发射器活动我有这onCreate:

AndroidObservable.bindActivity(this, Observable.just(Utils.isActiveInternetConnection(Launcher.this))) .subscribeOn(Schedulers.newThread()) .subscribe(new Action1<Boolean>() { @Override public void call(Boolean aBoolean) { if (aBoolean) { Toast.makeText(Launcher.this, "There is internet connection", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(Launcher.this, "There is no internet connection", Toast.LENGTH_SHORT).show(); } } }); 

我有一个Utils类,它是一个静态方法的最后一个类在observable使用的方法是这样的:

  public static boolean isActiveInternetConnection(Context context) { if (isNetworkAvailable(context)) { try { HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection()); urlc.setRequestProperty("User-Agent", "Test"); urlc.setRequestProperty("Connection", "close"); urlc.setConnectTimeout(1500); urlc.connect(); return (urlc.getResponseCode() == 200); } catch (IOException e) { Log.e("network", "Error checking internet connection", e); } } else { Log.d("network", "No network available!"); } return false; } private static boolean isNetworkAvailable(Context context){ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); if (null != activeNetwork) { return true; } else { return false; } } 

我收到android.os.NetworkOnMainThreadException,我无法find原因,在此先感谢。

Related of "android.os.NetworkOnMainThreadException在Android上使用rxjava"

Observable.just(...)立即在调用线程(在这种情况下是主线程)调用。 你的代码实际上只是这个内联版本:

 boolean activeConn = Utils.isActiveInternetConnection(Launcher.this); AndroidObservable.bindActivity(this, Observable.just(activeConn)) .subscribeOn(...) ... 

您试图通过调用subscribeOn()将其从主线程移出 – 但是调用已经发生。

我们处理这个问题的方法(我不确定这是最好的方法,但是它的工作原理)是延迟networking或阻塞呼叫,直到订阅发生,设置observable在正确的线程上运行,然后订阅:

 AndroidObservable.bindActivity(this, Observable.defer(new Func0<Boolean>() { @Override public Observable<Observable<Boolean>> call() { return Observable.just(Utils.isActiveInternetConnection(Launcher.this)); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Boolean>() { @Override public void call(Boolean aBoolean) { if (aBoolean) { Toast.makeText(Launcher.this, "There is internet connection", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(Launcher.this, "There is no internet connection", Toast.LENGTH_SHORT).show(); } } }); 

我想just调用方法同步,因为它期望的布尔值,它试图得到它。

我在RxJava相当糟糕,但是你可以尝试这样的事情:

 Observable<Boolean> onlineObservable = Observable.create(new Observable.OnSubscribe<Boolean>() { @Override public void call(Subscriber subscriber) { subscriber.onNext(Utils.isActiveInternetConnection(context)); } }); onlineObservable.subscribeOn(Schedulers.newThread()).subscribe(result -> {...}); 

这是我通过RXAndroid代码从DataBase中检索数据:

  Observable.create(new Observable.OnSubscribe<List<GRO_VO>>() { @Override public void call(Subscriber<? super List<GRO_VO>> subscriber) { String jsonIn; jsonIn =retrieveDataFromDB(); Gson gson = new Gson(); Type listType = new TypeToken<List<GRO_VO>>() { }.getType(); eventJoinList = gson.fromJson(jsonIn, listType); Log.d("RX",jsonIn); subscriber.onNext(eventJoinList); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<GRO_VO>>() { @Override public void call(List<GRO_VO> eventJoinList) { Log.d("RX", ".subscribe"); recyclerView.setAdapter(new EventJoinAdapter(eventJoinList)); } }); 

我认为just操作员会立即发送数据,所以通过networking从数据库中检索数据是没有用的。 它非常易于使用,但只能用于移动设备中已有的数据。

我也有这样的问题,就像@Baniares所做的那样,但是在我使用create操作符后,问题就消失了。

从RXJava文档:

static <T> Observable<T> create(Observable.OnSubscribe<T> f)

返回订阅者订阅时将执行指定函数的Observable。

使用create操作符可以build立标准过程:

.subscribe(...) Subscriber(Observer类的子类)启动到Observable的连接。

.subscribeOn(Schedulers.io())从RX-ThreadPool收集一个backGround线程

3。 .create(...)从服务器检索数据…在某些networking..等

4 .observeOn(AndroidSchedulers.mainThread())这意味着数据将由UI线程设置

5一旦我们获得了数据,我们可以在.subscribe()中的onNext()方法中设置数据,由于我们使UI线程在.observerOn(AndroidSchedulers.mainThread())上执行工作,UI-Thread上的数据将被设置在UI上.observerOn(AndroidSchedulers.mainThread())

方法链只是没有发生在代码上的顺序。

并注意,如果使用.create()运算符,则必须在.create()中完成您的observable,像map等其他运算符将不会在.create()运算符之后执行。

AdamS是正确的,但是RxJava 2现在提供Observable.fromCallable()来推迟一个可观察的操作直到订阅。 一个很好的参考: https : //caster.io/lessons/fromcallable-converting-slow-methods-into-an-observable/

我的用例中的一些示例代码:

 Single.fromCallable(new Callable<Response>() { @Override public Response call() throws Exception { return NetworkGateway.networkRequest(); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(observer);