Android is best practice for retrying IntentService

My Android app sends file uploads to Amazon S3. Each file URI is sent in separate calls to the IntentServiceone that performs the download.

However, I am wondering how best to deal with errors ... Should I detect a failure with my method IntentService onHandleIntent()and try again in the same method, OR should I allow failure processing outside the method (and if so, how?)?

I am personally inclined to the first sentence, since I would prefer that a file be successfully downloaded before subsequent files are downloaded, but I'm not sure if detecting errors and doing retries in the onHandleIntent()practice (?) Method .

+4
source share
1 answer

This is a very good question. I was asked about this in an interview, and I could not answer it. But I will try to answer it here after some searching for an answer.

Step-1: You start the IntentService. You can start IntentService from either Activity or Fragment.

/* Starting Download Service */

DownloadResultReceiver mReceiver = new DownloadResultReceiver(new Handler());
mReceiver.setReceiver(this);
Intent intent = new Intent(Intent.ACTION_SYNC, null, this, DownloadService.class);

/* Send optional extras to Download IntentService */
intent.putExtra("url", url);
intent.putExtra("receiver", mReceiver);
intent.putExtra("requestId", 101);
startService(intent);

Step-2: Make a class extending IntentService.

public class DownloadService extends IntentService {

    public static final int STATUS_RUNNING = 0;
    public static final int STATUS_FINISHED = 1;
    public static final int STATUS_ERROR = 2;

    private static final String TAG = "DownloadService";

    public DownloadService() {
        super(DownloadService.class.getName());
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        Log.d(TAG, "Service Started!");

        final ResultReceiver receiver = intent.getParcelableExtra("receiver");
        String url = intent.getStringExtra("url");

        Bundle bundle = new Bundle();

        if (!TextUtils.isEmpty(url)) {
            /* Update UI: Download Service is Running */
            receiver.send(STATUS_RUNNING, Bundle.EMPTY);

            try {
                String[] results = downloadData(url);//make your network call here and get the data or download a file.

                /* Sending result back to activity */
                if (null != results && results.length > 0) {
                    bundle.putStringArray("result", results);
                    receiver.send(STATUS_FINISHED, bundle);
                }
            } catch (Exception e) {

                /* Sending error message back to activity */
                bundle.putString(Intent.EXTRA_TEXT, e.toString());
                receiver.send(STATUS_ERROR, bundle);
            }
        }
        Log.d(TAG, "Service Stopping!");
        this.stopSelf();
    }
}

Step 3: To get the results from the IntentService, we can use the ResultReciever subclass. After the results are sent from the Service, the onReceiveResult () method is called. Your activity processes this response and fetches the results from the Bundle. After receiving the results, the corresponding activity instance updates the user interface.

public class DownloadResultReceiver extends ResultReceiver {
    private Receiver mReceiver;

    public DownloadResultReceiver(Handler handler) {
        super(handler);
    }

    public void setReceiver(Receiver receiver) {
        mReceiver = receiver;
    }

    public interface Receiver {
        public void onReceiveResult(int resultCode, Bundle resultData);
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        if (mReceiver != null) {
            mReceiver.onReceiveResult(resultCode, resultData);
        }
    }
}

-4: MainActivity:

@Override
    public void onReceiveResult(int resultCode, Bundle resultData) {
        switch (resultCode) {
            case DownloadService.STATUS_RUNNING:
                //progress bar visible.
                break;
            case DownloadService.STATUS_FINISHED:
                /* Hide progress & extract result from bundle */
                /* Update ListView with result */
                break;
            case DownloadService.STATUS_ERROR:
                /* Handle the error */
                String error = resultData.getString(Intent.EXTRA_TEXT);
                Toast.makeText(this, error, Toast.LENGTH_LONG).show();
                /*It is here, i think, that you can again check (eg your net connection) and call the IntentService to restart fetching of data from the network. */  
                break;
        }
    }

, . . .

+5

Source: https://habr.com/ru/post/1542476/


All Articles