[英]android.os.NetworkOnMainThreadException using rxjava on android
我在执行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类,它是带有静态方法的最终类,其中可观察到的方法是:
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,我找不到原因,谢谢。
Observable.just(...)
在调用线程(在本例中为主线程Observable.just(...)
上立即被调用。 您的代码实际上只是此代码的内联版本:
boolean activeConn = Utils.isActiveInternetConnection(Launcher.this);
AndroidObservable.bindActivity(this,
Observable.just(activeConn))
.subscribeOn(...)
...
您已经尝试通过调用subscribeOn()
将其移出主线程,但是该调用已经发生。
我们处理此问题的方法(并且我不确定这是否是最好的方法,但它是否有效)是将网络延迟或阻塞调用,直到订阅发生,将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();
}
}
});
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);
我猜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代码从数据库中检索数据:
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
操作符将立即发出数据,因此通过网络从数据库检索数据没有用。 它非常易于使用,但只能用于设备内存中的数据。
我也遇到了这个问题,就像@Baniares一样,但是在使用create
运算符后,所有问题都消失了……
从RXJava文档中:
static <T> Observable<T> create(Observable.OnSubscribe<T> f)
返回一个Observable,当订阅者订阅该Observable时将执行指定的函数。
使用create
运算符可以建立标准流程:
1 .subscribe(...)
订阅服务器(Observer类的子类)启动与Observable的连接。
2 .subscribeOn(Schedulers.io())
从RX-ThreadPool收集backGround线程
3 .create(...)
在一些网络中从服务器中检索数据..etc
4 .observeOn(AndroidSchedulers.mainThread())
这意味着数据将由UI-Thread设置
5一旦我们得到的数据,我们可以在该onNext()方法来设置数据.subscribe( )
数据将通过UI线程的UI,因为我们做的UI线程设置上做的工作.observerOn(AndroidSchedulers.mainThread())
请注意,如果使用.create()运算符,则必须在.create()中完成可观察性,其他操作符(如map,flatMap)将不会在.create()运算符之后执行。
在开始使用RXJava / RXAndroid之前,我们必须了解一个非常重要的概念。 RX是一个基于回调的库,您告诉RX在什么条件下应该做什么,它调用您的传入函数(或者在JAVA中,我可能应该将它们称为匿名内部类...)来实现所需的功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.