📜 ⬆️ ⬇️

Simple use of AsyncTask and ProgressDialog in Android

image

The practice of creating applications that are responsive to the actions of the user, assumes that all heavy operations must be executed in a separate thread, informing the user in one way or another about their progress.

Android contains a lot of ways to organize this approach, but one of the most convenient is the use of AsyncTask and ProgressDialog.
')
This couple perfectly solves the problem, but it starts to bring unbearable pain when the number of Activity with such logic passes for one, which leads to the repetition of the control code, and even more pain when the application must support changing the orientation of the screen.

AsyncTask

For those who are not familiar with AsyncTask, I will clarify that this is a special abstract class that provides a set of methods to implement:
and auxiliary methods
The essence of the problem

Using the mentioned classes is not difficult, just a couple of snippets are enough for the code to work as needed and ProgressDialog starts informing about the progress of the task. But, as you know, the devil is in the details, so you should only change the screen orientation, as the dialogue will disappear, as well as the result of a long, but incredibly responsible operation.

The reason is the life cycle of the Activity: changing the orientation of the screen is interpreted as a change of configuration, which leads to the re-creation of the Activity. You can, of course, disable this mechanism by setting the android:configChanges="orientation" tag of the Activity and defining your own code, which, if necessary, will make the necessary changes. But it will be an unreasonable introduction.

The solution will be to create a special class for managing the bundle Activity-AsyncTask-ProgressDialog, let's call it AsyncTaskManager.

Activity

So, ideally, our Activity should do only five things (code from the example project):
For the last point and reduce connectivity between the Activity and AsyncTaskManager, you can create an interface for notification of completion and implement it:

     public interface OnTaskCompleteListener {        void onTaskComplete(Task task);    } 

In the method parameter, the task will be transferred, the execution of which has been completed.

AsyncTaskManager

AsyncTaskManager should be responsible for the correct operation of all components, which boils down to the list of the following tasks:
To communicate with the task, the following interface is sufficient, which should be implemented and passed to the task:

     public interface IProgressTracker {        void onProgress(String message);        void onComplete();    } 

Implementation:

     @Override    public void onProgress(String message) {        if (!mProgressDialog.isShowing()) {            mProgressDialog.show();        }        mProgressDialog.setMessage(message);    }    @Override    public void onComplete() {        mProgressDialog.dismiss();        mAsyncTask.setProgressTracker(null);        mTaskCompleteListener.onTaskComplete(mAsyncTask);        mAsyncTask = null;    } 

Joining a task:

     mAsyncTask.setProgressTracker(this); 

Detaching from the task:

     mAsyncTask.setProgressTracker(null);    mAsyncTask = null; 

Cancel dialogue:

     @Override    public void onCancel(DialogInterface dialog) {        mAsyncTask.setProgressTracker(null);        mAsyncTask.cancel(true);        mTaskCompleteListener.onTaskComplete(mAsyncTask);        mAsyncTask = null;    } 

AsyncTaskManager performs the role of a peculiar key that connects and disconnects a running task to a possibly recreated Activity instance. In addition, it takes over and hides the logic of working with ProgressDialog.

AsyncTask


For the task, in addition to the implementation of the basic methods, the implementation of the method is required which will help to connect / disconnect it with AsyncTaskManager:

     public void setProgressTracker(IProgressTracker progressTracker) {        mProgressTracker = progressTracker;        if (mProgressTracker != null) {            mProgressTracker.onProgress(mProgressMessage);            if (mResult != null) {                mProgressTracker.onComplete();            }        }    } 

As can be seen from the above code, the task saves the calculated result and the last message about the progress, and, depending on the state, calls one or another tracker method (AsyncTaskManager).

Thus, even if the task is completed before the Activity is re-created, it will receive a notification of the completion of the task.

Result

Now you can safely turn the phone in your hands - all tasks will be processed correctly.

Using such a manager significantly reduces the amount of code in the Activity and allows you to reuse this functionality in the project. I developed this approach and successfully applied it in my recent application.

Links

Archive with draft project
AsyncTask Description (en)
Simple work with threads (en)
Conversations in Android (en)

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


All Articles