AsyncTask and error handling on Android

前端 未结 12 2110
失恋的感觉
失恋的感觉 2020-11-27 10:32

I\'m converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the

相关标签:
12条回答
  • 2020-11-27 11:02

    I made my own AsyncTask subclass with an interface that defines callbacks for success and failure. So if an exception is thrown in your AsyncTask, the onFailure function gets passed the exception, otherwise the onSuccess callback gets passed your result. Why android doesn't have something better available is beyond me.

    public class SafeAsyncTask<inBackgroundType, progressType, resultType>
    extends AsyncTask<inBackgroundType, progressType, resultType>  {
        protected Exception cancelledForEx = null;
        protected SafeAsyncTaskInterface callbackInterface;
    
        public interface SafeAsyncTaskInterface <cbInBackgroundType, cbResultType> {
            public Object backgroundTask(cbInBackgroundType[] params) throws Exception;
            public void onCancel(cbResultType result);
            public void onFailure(Exception ex);
            public void onSuccess(cbResultType result);
        }
    
        @Override
        protected void onPreExecute() {
            this.callbackInterface = (SafeAsyncTaskInterface) this;
        }
    
        @Override
        protected resultType doInBackground(inBackgroundType... params) {
            try {
                return (resultType) this.callbackInterface.backgroundTask(params);
            } catch (Exception ex) {
                this.cancelledForEx = ex;
                this.cancel(false);
                return null;
            }
        }
    
        @Override
        protected void onCancelled(resultType result) {
            if(this.cancelledForEx != null) {
                this.callbackInterface.onFailure(this.cancelledForEx);
            } else {
                this.callbackInterface.onCancel(result);
            }
        }
    
        @Override
        protected void onPostExecute(resultType result) {
            this.callbackInterface.onSuccess(result);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 11:04

    If you want to use the RoboGuice framework which brings you other benefits you can try the RoboAsyncTask which has an extra Callback onException(). Works real good and I use it. http://code.google.com/p/roboguice/wiki/RoboAsyncTask

    0 讨论(0)
  • 2020-11-27 11:05

    It works fine but is it the "right" approach and is there better alternative?

    I hold onto the Throwable or Exception in the AsyncTask instance itself and then do something with it in onPostExecute(), so my error handling has the option of displaying a dialog on-screen.

    0 讨论(0)
  • 2020-11-27 11:06

    A more comprehensive solution to Cagatay Kalan's solution is shown below:

    AsyncTaskResult

    public class AsyncTaskResult<T> 
    {
        private T result;
        private Exception error;
    
        public T getResult() 
        {
            return result;
        }
    
        public Exception getError() 
        {
            return error;
        }
    
        public AsyncTaskResult(T result) 
        {
            super();
            this.result = result;
        }
    
        public AsyncTaskResult(Exception error) {
            super();
            this.error = error;
        }
    }
    

    ExceptionHandlingAsyncTask

    public abstract class ExceptionHandlingAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, AsyncTaskResult<Result>>
    {
        private Context context;
    
        public ExceptionHandlingAsyncTask(Context context)
        {
            this.context = context;
        }
    
        public Context getContext()
        {
            return context;
        }
    
        @Override
        protected AsyncTaskResult<Result> doInBackground(Params... params)
        {
            try
            {
                return new AsyncTaskResult<Result>(doInBackground2(params));
            }
            catch (Exception e)
            {
                return new AsyncTaskResult<Result>(e);
            }
        }
    
        @Override
        protected void onPostExecute(AsyncTaskResult<Result> result)
        {
            if (result.getError() != null)
            {
                onPostException(result.getError());
            }
            else
            {
                onPostExecute2(result.getResult());
            }
            super.onPostExecute(result);
        }
    
        protected abstract Result doInBackground2(Params... params);
    
        protected abstract void onPostExecute2(Result result);
    
        protected void onPostException(Exception exception)
        {
                            new AlertDialog.Builder(context).setTitle(R.string.dialog_title_generic_error).setMessage(exception.getMessage())
                    .setIcon(android.R.drawable.ic_dialog_alert).setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int which)
                        {
                            //Nothing to do
                        }
                    }).show();
        }
    }
    

    Example Task

    public class ExampleTask extends ExceptionHandlingAsyncTask<String, Void, Result>
    {
        private ProgressDialog  dialog;
    
        public ExampleTask(Context ctx)
        {
            super(ctx);
            dialog = new ProgressDialog(ctx);
        }
    
        @Override
        protected void onPreExecute()
        {
            dialog.setMessage(getResources().getString(R.string.dialog_logging_in));
            dialog.show();
        }
    
        @Override
        protected Result doInBackground2(String... params)
        {
            return new Result();
        }
    
        @Override
        protected void onPostExecute2(Result result)
        {
            if (dialog.isShowing())
                dialog.dismiss();
            //handle result
        }
    
        @Override
        protected void onPostException(Exception exception)
        {
            if (dialog.isShowing())
                dialog.dismiss();
            super.onPostException(exception);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 11:08

    Personally, I will use this approach. You can just catch the exceptions and print out the stack trace if you need the info.

    make your task in background return a boolean value.

    it's like this:

        @Override
                    protected Boolean doInBackground(String... params) {
                        return readXmlFromWeb(params[0]);
             }
    
            @Override
                    protected void onPostExecute(Boolean result) {
    
                  if(result){
                  // no error
                   }
                  else{
                    // error handling
                   }
    }
    
    0 讨论(0)
  • 2020-11-27 11:09

    This simple class can help you

    public abstract class ExceptionAsyncTask<Param, Progress, Result, Except extends Throwable> extends AsyncTask<Param, Progress, Result> {
        private Except thrown;
    
        @SuppressWarnings("unchecked")
        @Override
        /**
         * Do not override this method, override doInBackgroundWithException instead
         */
        protected Result doInBackground(Param... params) {
            Result res = null;
            try {
                res = doInBackgroundWithException(params);
            } catch (Throwable e) {
                thrown = (Except) e;
            }
            return res;
        }
    
        protected abstract Result doInBackgroundWithException(Param... params) throws Except;
    
        @Override
        /**
         * Don not override this method, override void onPostExecute(Result result, Except exception) instead
         */
        protected void onPostExecute(Result result) {
            onPostExecute(result, thrown);
            super.onPostExecute(result);
        }
    
        protected abstract void onPostExecute(Result result, Except exception);
    }
    
    0 讨论(0)
提交回复
热议问题