Интернет-проверка, где разместить при использовании MVP, RX и дооснащение

Я прошел через этот и этот пост. Поэтому я действительно согласен со вторым сообщением, что ведущий не должен знать о специфике Android. Так что я думаю, что это интернет-проверка на уровне обслуживания. Я использую Rx Java для создания сетевых вызовов, поэтому я могу либо поставить сетевую проверку перед вызовом службы, так что мне нужно вручную бросить и IOException, потому что мне нужно показать страницу с ошибкой при просмотре, когда сеть недоступна, Другой вариант – я создаю свой собственный класс ошибок без Интернета

Observable<PaginationResponse<Notification>> response = Observable.create(new Observable.OnSubscribe<PaginationResponse<Notification>>() { @Override public void call(Subscriber<? super PaginationResponse<Notification>> subscriber) { if (isNetworkConnected()) { Call<List<Notification>> call = mService.getNotifications(); try { Response<List<Notification>> response = call.execute(); processPaginationResponse(subscriber, response); } catch (IOException e) { e.printStackTrace(); subscriber.onError(e); } } else { //This is I am adding manually subscriber.onError(new IOException); } subscriber.onCompleted(); } }); 

Другой способ, по-моему, добавить перехватчик в OkHttpClient и настроить его на модификацию

 OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); builder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { if (!isNetworkConnected()) { throw new IOException(); } final Request.Builder builder = chain.request().newBuilder(); Request request = builder.build(); return chain.proceed(request); } }); 

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

Любое предложение, каким образом следует использовать? Также мой параметр для оценки пути

  • КПД

  • Масштабируемость

  • Generic: Я хочу, чтобы эта же логика могла использоваться в приложениях, которые следуют аналогичной архитектуре, где MVP и репозиторий / DataProvider (могут давать данные из сети / db)

Другие предложения также приветствуются, если вы уже используете какой-либо другой способ.

Solutions Collecting From Web of "Интернет-проверка, где разместить при использовании MVP, RX и дооснащение"

Сначала мы создаем утилиту для проверки подключения к Интернету, есть два способа создать эту утилиту: ту, где утилита выдает статус только один раз, что выглядит так:

 public class InternetConnection { public static Observable<Boolean> isInternetOn(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return Observable.just(activeNetworkInfo != null && activeNetworkInfo.isConnected()); } } 

Другим способом создания этой утилиты является то, что утилита продолжает излучать статус соединения, если она изменяется, что выглядит следующим образом:

 public class InternetConnection { public Observable<Boolean> isInternetOn(Context context) { final IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); return Observable.create(new Observable.OnSubscribe<Boolean>() { @Override public void call(final Subscriber<? super Boolean> subscriber) { final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); subscriber.onNext(netInfo != null && netInfo.isConnected()); } }; context.registerReceiver(receiver, filter); subscriber.add(unsubscribeInUiThread(() -> context.unregisterReceiver(receiver))); } }).defaultIfEmpty(false); } private Subscription unsubscribeInUiThread(final Action0 unsubscribe) { return Subscriptions.create(() -> { if (Looper.getMainLooper() == Looper.myLooper()) { unsubscribe.call(); } else { final Scheduler.Worker inner = AndroidSchedulers.mainThread().createWorker(); inner.schedule(() -> { unsubscribe.call(); inner.unsubscribe(); }); } }); } } 

Затем в вашем источнике данных или презентаторе используйте switchMap или flatMap, чтобы проверить подключение к Интернету, прежде чем выполнять какую-либо операцию в сети, которая выглядит так,

 private Observable<List<GitHubUser>> getGitHubUsersFromRetrofit() { return isInternetOn(context) .filter(connectionStatus -> connectionStatus) .switchMap(connectionStatus -> gitHubApiInterface.getGitHubUsersList() .map(gitHubUserList -> { gitHubUserDao.storeOrUpdateGitHubUserList(gitHubUserList); return gitHubUserList; })); } 

Обратите внимание, что мы используем switchMap вместо flatMap. Почему switchMap? Потому что у нас есть 2 потока данных здесь, сначала это интернет-соединение, а второе – «Дооснащение». Сначала мы получим значение статуса соединения (true / false), если у нас есть активное соединение, мы создадим новый поток Retrofit и начнем получать результаты, по линии, если мы изменим статус соединения, switchMap сначала остановит существующий Переустановите соединение, а затем решите, нужно ли нам начинать новый или игнорировать его.

EDIT: Это один из примеров, который может дать лучшую ясность https://github.com/viraj49/Realm_android-injection-rx-test/blob/master/app-safeIntegration/src/main/java/tank/viraj/ область / DataSource / GitHubUserListDataSource.java

EDIT2:

Значит, вы имеете в виду, что карта коммутатора попробует ее, как только интернет вернется?

Да и Нет, давайте сначала посмотрим разницу между flatMap и switchMap. Допустим, у нас есть editText, и мы просматриваем информацию из сети на основе того, какие типы пользователей, каждый раз, когда пользователь добавляет новый символ, мы должны сделать новый запрос (который может быть уменьшен с помощью debounce), теперь с таким количеством сетевых вызовов только Последние результаты полезны, с flatMap мы получим все результаты от всех вызовов, которые мы сделали в сети, с коммутацией, с другой стороны, в момент, когда мы делаем запрос, все предыдущие вызовы отбрасываются.

Теперь решение здесь состоит из двух частей,

  1. Нам нужен Observable, который сохраняет испускание текущего состояния сети, первый InternetConnection выше отправляет статус один раз и вызывает onComplete (), но второй имеет широковещательный приемник, и он будет продолжать отправлять onNext () при изменении состояния сети. ЕСЛИ вам нужно сделать реактивное решение для случая-2

  2. Предположим, вы выбрали case-2 для InternetConnection, в этом случае используйте switchMap (), вызывая изменение статуса сети, нам нужно остановить «Дооснащение» из того, что он делает, а затем в зависимости от статуса сети либо сделать новый вызов, либо не сделать позвонить.

Как я могу сообщить своему представлению о том, что ошибка является интернетом, и это будет масштабируемо, потому что мне нужно делать с каждым сетевым вызовом любые предложения относительно написания обертки?

Написание обертки было бы отличным выбором, вы можете создать свой собственный ответ, который может принимать несколько записей из набора возможных ответов, например SUCCESS_INTERNET, SUCCESS_LOGIN, ERROR_INVALID_ID

EDIT3: найдите обновленный InternetConnectionUtil здесь https://github.com/viraj49/Realm_android-injection-rx-test/blob/master/app-safeIntegration/src/main/java/tank/viraj/realm/util/InternetConnection. Ява

Более подробно по этой же теме можно найти здесь: https://medium.com/@Viraj.Tank/android-mvp-that-survives-view-life-cycle-configuration-internet-changes-part-2-6b1e2b5c5294

EDIT4: Недавно я создал интернет-утилиту с использованием компонентов Android Architecture – LiveData, здесь вы можете найти полный исходный код, https://github.com/viraj49/Internet-Utitliy-using-AAC-LiveData

Подробное описание кода приведено здесь: https://medium.com/@Viraj.Tank/internet-utility-using-android-architecture-components-livedata-e828a0fcd3db