Android - Handling errors from Loaders

      Android's Loader API is generalized just to handle results from the background tasks.

                             android.content.AsyncTaskLoader<D>

 This is fine in most cases as the primary reason to use Loader is to do some operation in background and get the results. However, this by itself is not good enough as background tasks like network operations usually come with strings attached and is associated with multiple error scenarios like network timeout, lost connection, unreachable destination. Besides, the application layer protocol might have other custom errors too. So how to deal with this possibility and update UI accordingly?

  Here is a Loader which would fail randomly,

    private static class FailSometimeLoader extends AsyncTaskLoader<List> {

        int mErrorCode;
        List<String> mData;

        public FailSometimeLoader(Context context) {
            super( context );
        }

        @Override
        protected void onStartLoading() {
            mErrorCode = 0;            
            forceLoad();
        }

        @Override
        public List loadInBackground() {
            mData = new ArrayList<String>();

            if ( System.currentTimeMillis()% 2 == 0 ) {
                mErrorCode = 0;
                mData.add("Call Of Duty : Modern Warfare");
                mData.add("Madden 15");
                mData.add("NHL 15");
                mData.add("Madden 25");
            }
            else {
                mErrorCode = -1;
            }

            return mData;
        }

        public int getErrorCode() {
            return mErrorCode;
        }
    }


   The activity implementing the LoaderManager.LoaderCallbacks would get a reference to the loader in the onLoadFinished() callback. This generic loader reference can be typecasted to the specific concrete FailSometimeLoader and getErrorCode() can be invoked to check for the error status.

    @Override
    public void onLoadFinished(Loader<List> listLoader, List list) {

        FailSometimeLoader loader = ( FailSometimeLoader ) listLoader;

        int errorCode = loader.getErrorCode();

        if ( errorCode == 0 ) {
            ListView listView = (ListView) findViewById( R.id.sample_list );
            listView.setAdapter( new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, list ));
        }
        else {
            Toast.makeText( this, "Loading in background failed with [" + errorCode + "]", Toast.LENGTH_SHORT).show();
        }
    }

No comments: