我在实施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,我无法找到原因,提前谢谢。
答案 0 :(得分:17)
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();
}
}
});
答案 1 :(得分:1)
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);
答案 2 :(得分:0)
我猜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 -> {...});
答案 3 :(得分:0)
这是我通过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
运算符会立即发出数据,因此它无法通过网络从数据库中检索数据。它非常易于使用,但它只能用于已经在设备内部的数据。
我也有这个问题,就像@Baniares一样,但在我使用create
运算符之后,所有问题都消失了......
来自RXJava文档:
static <T> Observable<T> create(Observable.OnSubscribe<T> f)
返回一个Observable,当订阅者订阅它时将执行指定的函数。
使用create
运算符可以建立标准流程:
1 .subscribe(...)
订阅者(Observer类的子类)启动与Observable的连接。
2 .subscribeOn(Schedulers.io())
从RX-ThreadPool收集一个backGround线程
3 .create(...)
在某些netWork..etc
4 .observeOn(AndroidSchedulers.mainThread())
这意味着数据将由UI-Thread
5一旦我们得到数据,我们就可以在.subscribe( )
的onNext()方法中设置数据,因为我们让UI-thread完成工作,所以UI-Thread上的数据将被设置在UI上在.observerOn(AndroidSchedulers.mainThread())
请注意,如果使用.create()运算符,则必须在.create()中完成observable,其他运算符如map,flatMap将不会在.create()运算符后执行。
在开始使用RXJava / RXAndroid之前我们必须知道的一个非常重要的概念。 RX是一个基于回调的库,你告诉RX它应该在什么条件下做什么,它调用你的传入函数(或者在JAVA中我可能应该称之为匿名内部类......)来实现你想要的。