Helper methods to check network connectivity on Android (RxJava2)

744 views
Skip to first unread message

tadej....@bjss.com

unread,
Jun 9, 2017, 5:17:03 AM6/9/17
to RxJava
Hi all,

assume my Android app has this amazing Retrofit API:

interface AmazingApi {
 
@POST("/login")
 
Single<LoginInfo> login(@Body LoginBody body);
 
 
@POST("/logout")
 
Completable logout(@Body LogoutBody body);

 
@GET("/cool/{things}")
 
Observable<String> things(@Path("things") String things);

 
@GET("/gazillion/cool/{things}")
 
Flowable<String> gazillionThings(@Path("things") String things);
}


Before executing any of the methods, I’d like to check if network is available. As I have multiple source types (Single, Completable, etc.) I’ve implemented the following helper methods: 

private <T> Single<T> withNetworkCheck(@NonNull Single<T> continuation) {
 
if (isOnline(context)) {
   
return continuation.onErrorResumeNext(throwable -> {
     
return Single.error(asHttpThrowable(throwable));
   
});
 
}
 
final String err = context.getString(R.string.offline);
 
return Single.error(new Throwable(err));
}
 
private <T> Observable<T> withNetworkCheck(@NonNull Observable<T> continuation) {
  // Same impl. as above, but Observable instead of Single.
}


private Completable withNetworkCheck(@NonNull Completable continuation) {
 
// Same impl. as above, but Completable instead of Single.
}

// etc.

This yields the following calls:

withNetworkCheck(api.login(body));
withNetworkCheck
(api.logout(body));
withNetworkCheck
(api.things("foo"));

which is alright, but I'm not too happy with the amount of duplication in the helper methods.

Being relatively unexperienced with RxJava, I’m sure there’s a better/more elegant way of doing the above. Any help/hints?

Thanks!

Joshua Pierce

unread,
Jun 12, 2017, 9:40:32 AM6/12/17
to RxJava
I know you are looking for an Rx solution but since you mentioned that you are using Retrofit...

Why not just make the network check part of the network flow? I assume you want to check connectivity before every request?  And since you're just throwing an error, you can easily create a custom interceptor that will do exactly that:

class CheckConnectivityInterceptor(private val connMan: ConnectivityManager) : Interceptor {

 
@Throws(IOException::class)
 
override fun intercept(chain: Interceptor.Chain): Response {

 val netInfo
= connMan.activeNetworkInfo
 
if (netInfo == null || !netInfo.isConnected) {
 
throw NoNetworkException()
 
}

 
return chain.proceed(chain.request())
 
}
}

class NoNetworkException : IOException()

To use this you just instantiate it when you create your Retrofit instance (by adding it to an anonymous OkHttp client):

Retrofit.Builder()
 
.baseUrl(baseUrl)
 
.client(
   
OkHttpClient.Builder()
     
.addInterceptor(CheckConnectivityInterceptor())
     
.build()
 
)
 
...finish building here...
 
.build()

Now you will receive NoNetworkException in onError when there is no connection.
Reply all
Reply to author
Forward
0 new messages