An example tutorial of making cool progress bar through AsyncTask class in Android

  • 2021-07-10 20:50:12
  • OfStack

AsyncTask (API level 3, so almost all Android versions currently in circulation can be used)
Is an alternative to Thread, and the Android team encourages the main thread (UI thread) to focus on operations & The smooth presentation of the picture,
The rest of the work (such as network data transfer, file/disk/data access) is preferably performed in the background;
Thread is usually used with Handler, while AsyncTask is intended to simplify the writing of thread program code for background execution.

If you expect the work to be done in a few seconds, you can choose to use AsyncTask. If the execution time is very long,
Android strongly recommends Executor, ThreadPoolExecutor and FutureTask.

To use AsyncTask, you must create a subclass that inherits from AsyncTask and pass in three items of data:

Params-The number of parameters passed in to execute doInBackground () can be more than 1 Progress-Data returned to UI thread during the execution of doInBackground (), the number can be more than 1 Rsesult--Returns execution results

If you have no parameters to pass in, fill in Void (note that V is capitalized).

AsyncTask operates in four phases:

onPreExecute--Preparations before AsyncTask is executed, such as showing a schedule on the screen, doInBackground-the actual program code to be executed is written here, onProgressUpdate-Used to show current progress, onPostExecute--The result of execution--Result is passed in here.

Except for doInBackground, the other three method are all called at UI thread


Example of Cool Progress Bar
Let's take an example to illustrate, "Click the button to start downloading the QQAndroid installation package, and then display a dialog box to feedback the download progress". Let's initialize a dialog box first, To display progress, We use Github above a progress bar that can show the percentage NumberProgressbar, the button to start the task we use circlebutton, a button with cool animation, Github has many very good open source projects, of course, cool controls are one part of it, and there is an opportunity later to learn some popular controls their implementation principles, so let's take them to doctrine for the time being.

1. Initialize the progress bar prompt dialog box first.


 builder = new AlertDialog.Builder(
     MainActivity.this);
 LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
 mDialogView = inflater.inflate(R.layout.progress_dialog_layout, null);
 mNumberProgressBar = (NumberProgressBar)mDialogView.findViewById(R.id.number_progress_bar);
 builder.setView(mDialogView);
 mDialog = builder.create();

2. Set the button click event.


 findViewById(R.id.circle_btn).setOnClickListener(new View.OnClickListener(){
   @Override
   public void onClick(View v) {
     dismissDialog();
     mNumberProgressBar.setProgress(0);
     myTask = new MyAsyncTask();
     myTask.execute(qqDownloadUrl);
   }
 });

3. DownloadAsyncTask implementation, a bit long.


private class DownloadAsyncTask extends AsyncTask<String , Integer, String> {

 @Override
 protected void onPreExecute() {
   super.onPreExecute();
   mDialog.show();

 }

 @Override
 protected void onPostExecute(String aVoid) {
   super.onPostExecute(aVoid);
   dismissDialog();
 }

 @Override
 protected void onProgressUpdate(Integer... values) {
   super.onProgressUpdate(values);

   mNumberProgressBar.setProgress(values[0]);
 }

 @Override
 protected void onCancelled(String aVoid) {
   super.onCancelled(aVoid);
   dismissDialog();
 }

 @Override
 protected void onCancelled() {
   super.onCancelled();
   dismissDialog();
 }

 @Override
 protected String doInBackground(String... params) {
   String urlStr = params[0];
   FileOutputStream output = null;
   try {
     URL url = new URL(urlStr);
     HttpURLConnection connection = (HttpURLConnection)url.openConnection();
     String qqApkFile = "qqApkFile";
     File file = new File(Environment.getExternalStorageDirectory() + "/" + qqApkFile);
     if (file.exists()) {
       file.delete();
     }
     file.createNewFile();
     InputStream input = connection.getInputStream();
     output = new FileOutputStream(file);
     int total = connection.getContentLength();
     if (total <= 0) {
       return null;
     }
     int plus = 0;
     int totalRead = 0;
     byte[] buffer = new byte[4*1024];
     while((plus = input.read(buffer)) != -1){
       output.write(buffer);
       totalRead += plus;
       publishProgress(totalRead * 100 / total);
       if (isCancelled()) {
         break;
       }
     }
     output.flush();
   } catch (MalformedURLException e) {
     e.printStackTrace();
     if (output != null) {
       try {
         output.close();
       } catch (IOException e2) {
         e2.printStackTrace();
       }
     }
   } catch (IOException e) {
     e.printStackTrace();
     if (output != null) {
       try {
         output.close();
       } catch (IOException e2) {
         e2.printStackTrace();
       }
     }
   } finally {
     if (output != null) {
       try {
         output.close();
       } catch (IOException e) {
         e.printStackTrace();
       }
     }
   }
   return null;
 }
}

In this way, a simple download file is basically realized, So far, there is no skill. But now we have a problem, That is, if our Activity is executing a task in the background, which may take a long time, the user may click back to exit Activity or exit App, so the background task will not exit immediately. If there is a reference to the member variable in Activity in AsyncTask, it will also cause the recycling delay of Activity, resulting in memory leakage within a period of time, so we need to add the following step 4.

4. In onPause, it is judged whether the application wants to exit, so as to decide whether to cancel the execution of AsyncTask.


@Override
protected void onPause() {
 super.onPause();
 if (myTask != null && isFinishing()) {
   myTask.cancel(false);
 }
}

In this way, when Activity exits, our asynchronous task will be cancelled and successfully destroyed and recycled by the system. Step 4 will often be missed, and there will be no fatal problems in general. However, once something goes wrong, it is difficult to check, so it is necessary to follow the coding specification.



Related articles: