I have a content provider which performs database or network requests. If there is no network, an IOException is raised and I would like to do another request (on the database this time).
My code looks like
/**
* Content provider
*/
//...
public Cursor query (Uri uri /*,...*/) {
switch(uriMatcher.match(uri)) {
case NETWORK:
JSONObject json;
try {
json = new HttpTask().getItems(); // If no network throws IoException
} catch (IOException e) {
//Do something
}
return new Cursor(/* ... */);
break;
case DATABASE:
//Access database
return new Cursor(/* ... */);
break;
}
}
//...
Should I :
- Handle the exception only in the contentProvider and directly move to the database case if an error occured ?
- Handle the exception in the
HttpTask
so thejson
will "just" be null - Create a custom cursorloader like this one and a custom RuntimeException ? If so, within the content provider I will able to throw the exception and catch it in the CursorLoader.
EDIT 1
Or should I check the network state before using :
ConnectivityManager connectivityManager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
NetworkInfo ni = connectivityManager.getActiveNetworkInfo();
if (ni.getState() != NetworkInfo.State.CONNECTED) {
// record the fact that there is not connection
isConnected = false;
}
}
EDIT 2 Here is how to do using a custom exception and a custom loader
NoNetworkException.java
public class NoNetworkException extends RuntimeException {
public NoNetworkException(String s) {
super(s);
}
}
NoNetworkSafeCursorLoader.java
public class NoNetworkSafeCursorLoader extends CursorLoader {
private NoNetworkException exception;
public NoNetworkSafeCursorLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
super(context, uri, projection, selection, selectionArgs, sortOrder);
}
@Override
public Cursor loadInBackground() {
try {
return super.loadInBackground();
} catch(NoNetworkException exception) {
this.exception = exception;
}
return null;
}
public NoNetworkException getException() {
return exception;
}
}
Now in the content provider you need to throw NoNetworkException
//...
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) throws NoNetworkException {
//...
}
//...
and in the callback you must check if an exception was thrown
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) throws NoNetworkException {
NoNetworkSafeCursorLoader l = (NoNetworkSafeCursorLoader) loader;
if(l.getException() != null) {
//No network, do somethings
}
else {
//Network ok, do otherthings
}
}