Android 多線程之AsyncTask學習

目錄

1. 定義

1.1 3個泛型參數介紹

1.2 任務執行的4個步驟

2. Demo例子


1. 定義

官方解釋:AsyncTask可以正確及方便地使用UI線程。此類允許您執行後臺操作並在UI線程上發佈結果,而無需通過操作Thread和Handler。AsyncTasks應該用於短操作(最多幾秒鐘)。異步任務在後臺線程運行計算,其結果在UI線程上發佈。

1.1 3個泛型參數介紹

java.lang.Object
   ↳	android.os.AsyncTask<Params, Progress, Result>

1. Params(傳入參數類型):execute() 執行時傳入給Task的參數。

2. Progress(執行進度類型):異步任務在後臺執行的進度單位類型。

3. Result(執行結果類型):後臺執行完異步任務計算返回的結果類型。

如果不執行,則Void類型,如:

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

1.2 任務執行的4個步驟

1、onPreExecute():在UI線程中工作,在doInBackground()任務計算前執行

2、doInBackground(Params...):在線程池中工作,所以不可任何UI操作,在onPreExecute()執行結束後立即執行,用與執行長時間的計算工作(即耗時工作),Params參數是通過在主線程中調用execute()方法傳入。計算工作完成後就會將計算結果返回給onPostExecute(Result)方法。也可以通過調用publishProgress(Progress)方法將 執行進度 傳遞給onProgressUpdate(Progress)方法。

3、onProgressUpdate(Progress...):在UI線程中工作,會在doInBackground()中執行publishProgress()方法後執行,此方法用於在後臺計算仍在執行時(也就是doInBackgound()還在執行是)將計算執行進度通過UI顯示出來,方便用戶知道後臺任務執行的進度。

4、onPostExecute(Result):在UI線程中工作,在doInBackground()執行完將結果傳入過來後執行。

 

2. Demo例子

詳細代碼:

public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {
    private ProgressBar progressBar;
    private TextView displayTv;
    private Button startBtn, stopBtn;
    private MyAsyncTask myAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_task);

        progressBar = findViewById(R.id.progress_bar);
        displayTv = findViewById(R.id.display_tv);
        startBtn = findViewById(R.id.start_btn);
        stopBtn = findViewById(R.id.stop_btn);
        myAsyncTask = new MyAsyncTask();

        startBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.start_btn:
                myAsyncTask.execute("Jere test");
                //AsyncTask只能執行一次,如果你在AsyncTask執行過程中再次調用 execute() 執行它,就會跳IllegalStateException異常
                //java.lang.IllegalStateException: Cannot execute task: the task is already running.
                startBtn.setEnabled(false);
                break;
            case R.id.stop_btn:
                //中斷線程執行
                myAsyncTask.cancel(true);
                break;
            default:
                break;
        }
    }

    /**
     * 創建MyAsyncTask類, 繼承AsyncTask類 -> AsyncTask<Params, Progress, Result>
     * 3個泛型參數指定類型:
     * Params(輸入參數): String類型
     * Progress(執行進度): Integer類型
     * Result(執行結果): String類型
     */
    private class MyAsyncTask extends AsyncTask<String, Integer, String> {

        /**
         * 在後臺任務開始計算執行前執行onPreExecute()操作
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            displayTv.setText("onPreExecute: start! ");
            Toast.makeText(AsyncTaskActivity.this, "onPreExecute", Toast.LENGTH_SHORT).show();
        }

        /**
         * 接收輸入參數,執行後臺任務中的計算工作(耗時操作),計算結束,返回計算結果
         * @param strings Params輸入參數,在主線程執行execute()傳入的參數
         * @return 返回執行結果給onPostExecute()
         */
        @Override
        protected String doInBackground(String... strings) {
            for (int i = 1; i <= 10; i++) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //通過調用publishProgress()方法,將執行進度傳遞給onProgressUpdate()
                publishProgress(i);
            }

            String result;
            result = Arrays.toString(strings) + " return from doInBackground";
            return result;
        }

        /**
         * 接收後臺計算執行進度,在UI線程中通過ProgressBar現實執行進度。
         * @param values : 執行進度,通過publishProgress()傳入
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            //得到一個整型數組,但每次裏面只有一個元素,所有通過values[0]就可以拿到當前的執行進度
            progressBar.setProgress(values[0]);
            displayTv.setText("onProgressUpdate: value = " + values[0]);
        }

        /**
         * 接收後臺任務計算結束返回的結果,在UI線程上顯示出來
         * @param s :後臺計算結束返回的執行結果,由doInBackground()返回
         */
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            displayTv.setText("onPostExecute: " + s);
            Toast.makeText(AsyncTaskActivity.this, "onPostExecute", Toast.LENGTH_SHORT).show();
        }

        /**
         * 在主線程中調用cancel()方法,執行onCancelled(),取消執行後臺任務
         *
         * 當任務計算完成時,無法取消任務,或者已經取消任務後不可再次取消
         */
        @Override
        protected void onCancelled() {
            super.onCancelled();
            displayTv.setText("onCancelled");
            progressBar.setProgress(0);
            Toast.makeText(AsyncTaskActivity.this, "onCancelled", Toast.LENGTH_SHORT).show();
        }

    }

}

額外中斷任務的效果如下:👇

 

具體代碼請看 👉 源代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章