Android.os.NetworkOnMainThreadException с помощью rxjava на 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(...) вызывается немедленно на вызывающей нити (в этом случае основной поток). Ваш код является фактически просто встроенной версией этого:

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

Вы попытались переместить его из основного потока, вызвав subscribeOn() – но вызов уже произошел.

То, как мы справляемся с этим (и я не уверен, что это лучший способ, но он работает) заключается в том, чтобы отложить сеть или заблокировать вызов до тех пор, пока не произойдет подписка, настройте наблюдаемое для запуска на правильные потоки и затем подписаться:

 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 в 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, который будет выполнять указанную функцию, когда подписчик подписывается на нее.

Использование оператора create может установить стандартный процесс:

1 .subscribe(...) Подписчик (подкласс класса Observer) начинает соединение с Observable.

2 .subscribeOn(Schedulers.io()) собирает обратную нить из RX-ThreadPool

3 .create(...) извлекать данные с сервера … во время некоторого netWork..etc

4 .observeOn(AndroidSchedulers.mainThread()) это означает, что данные будут устанавливаться с помощью UI-Thread

5 Как только мы получим данные, мы можем установить данные в методе onNext () в .subscribe( ) , данные будут установлены в пользовательском интерфейсе UI-Thread, поскольку мы создаем UI-поток для работы с .observerOn(AndroidSchedulers.mainThread())

Цепочка методов просто не выполняется по порядку в коде.

Обратите внимание: если вы используете оператор .create (), вы должны закончить свое наблюдение в .create (), другой оператор, такой как map, flatMap не будет выполнен после оператора .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); 

Ваш метод isActiveInternetConnection пытается подключиться к сети из основного потока приложения, попробуйте использовать обработчик или asynctask для этого метода. Дополнительная информация об ошибке: Как исправить android.os.NetworkOnMainThreadException?

Intereting Posts
О порте SMS для Android Как проверить видимость параметра меню меню в Robolectric? Android Studio Emulator не запускается Установить уведомление о тревоге Виджет приложений onUpdate не вызывается, когда существует метод onReceive Клавиатура Android InputType без EditText Ограничить пропускную способность с помощью RxJava Примечание: в конфигурации сохраняется точка входа `XXX`, но не класс дескриптора 'xxx' в Android Studio Android: Как читать файл в байтах? Попытка подключиться к XMPP-серверу с помощью aSmack на Android дает мне «no dns resolver active» Зачем мне нужно setRetainInstance или onSaveInstance, если я могу использовать android: configChanges = "keyboard | orientation | screenLayout" В Android, как я могу узнать текущий идентификатор уведомления, чтобы очистить уведомление Каковы плюсы и минусы использования нескольких процессов в приложении android Android без активности getSharedPreferences C2DM: Могу ли я регистрироваться для нескольких идентификаторов-отправителей в одном приложении?