Правильно обрабатывать отключение интернета

В большинстве случаев нам все равно, что у нас нет интернета, пока мы не вызовем API. Более сложный случай, когда нам нужно предупредить пользователя, как только интернет пропадет.

Как постоянно мониторить интернет?

Во-первых, подключение к сети не означает наличие доступа к Интернету.

Устройство может быть подключено к маршрутизатору, который не подключается к Интернету.

Единственный способ убедиться, что Интернет доступен, — это протестировать что-то в Интернете. Короче говоря, мы можем пропинговать Google. Мы обсудим элегантный способ сделать это позже.



Как постоянно контролировать сеть?

Метод отличается в зависимости от версии ОС Android.

Перед Lollipop (API 20 или ниже)

Использует широковещательный приемник. Зарегистрируйте рассылку и проверяйте статус с помощьюConnectivityManager каждый раз, когда получаете рассылку.

пример:



https://gist.github.com/Aeonitis/2e4df7a3b861edeb4b7d03e900bda633

После Lollipop (API 21 или выше)

Использует API сетевого обратного вызова. Начиная с API 21, класс ConnectivityManager предоставляет класс NetworkCallback .

Этот обратный вызов предоставляет полезные методы, такие как onAvailable(Network network) и onLost(Network network) .

Пример:



После Lollipop (API 24 или выше)

Мы можем использовать registerDefaultNetworkCallback в ConnectivityManager

Пример:

https://gist.github.com/PasanBhanu/730a32a9eeb180ec2950c172d54bb06a

Посмотрите, как это делают профессионалы

Чтобы контролировать Интернет, мы должны реализовать некоторую функцию для многократного пинга удаленного сервера. Это хлопотно.

Поэтому мы можем проанализировать исходный код какой-нибудь хорошо сделанной библиотеки и посмотреть, как они ее реализуют. Я рекомендую ReactiveNework от pwittchen.



Его readme действительно полезен, пожалуйста, прочтите его. Я не собираюсь копировать то, что там есть.

Он по-прежнему использует описанную выше логику, но красиво упаковал все в свои собственные стратегии с использованием RxJava. (Даже управлял потоками для вас, что еще можно желать!)

Его стратегия до Lollipop (API 20 или ниже)

https://github.com/pwittchen/ReactiveNetwork/blob/RxJava2.x/library/src/main/java/com/github/pwittchen/reactivenetwork/library/rx2/network/observing/strategy/PreLollipopNetworkObservingStrategy.java

Красное поле показывает, что он регистрирует приемник с IntentFilter фильтром на CONNECTIVITY_ACTION

Его стратегия после Lollipop (API 21 или выше)

https://github.com/pwittchen/ReactiveNetwork/blob/RxJava2.x/library/src/main/java/com/github/pwittchen/reactivenetwork/library/rx2/network/observing/strategy/LollipopNetworkObservingStrategy.java

Красная линия показывает, что он вызывает передачу registerNetworkCallback() в networkCallback.

Его стратегия проверки интернета

https://github.com/pwittchen/ReactiveNetwork/blob/RxJava2.x/library/src/main/java/com/github/pwittchen/reactivenetwork/library/rx2/internet/observing/strategy/SocketInternetObservingStrategy.java

У него есть функция isConnected(), которая принимает хост и порт для открытия сокета.
И все это заключено в интервал RxJava для многократного выполнения.

Видеть? Здесь используется та же логика, здесь нет ничего волшебного. Нам удобнее пользоваться библиотекой, если мы понимаем, как она работает.

Имейте некоторую терпимость

Один из советов: не выводить сообщение об ошибке, как только мы обнаружим событие потери интернета.

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

Правильный способ сделать это - установить набор задержек. Если мы обнаружим, что Интернет потерян, подождите 1 секунду, затем проверьте еще раз. Если все еще не удается, подождите 2 секунды и проверьте снова. Если все еще не удается, подождите 4 секунды, чтобы проверить снова. Если все эти проверки не пройдены, мы выводим сообщение об ошибке, чтобы изменить пользователя, попросить его повторить попытку или проверить свой интернет.