AsyncTask 的使用

AsyncTask 簡介

AsyncTask 是一個輕量級的異步任務類,它內部封裝了Thread和Handler可以用它在線程池中執行後臺異步任務,然後把執行進度和最終結果傳遞給主線程並在主線程中更新UI。

AsyncTask 參數

AsyncTask 是一個抽象的泛型類,提供了Params、Progress、Result三個泛型參數
Params:參數類型
Progress: 任務進度的類型
Result:任務返回結果類型
如果確實不需要傳遞具體的參數,可用Void來代替

AsyncTask 核心方法

  • onPreExecute() 主線程執行,在異步任務執行前被調用,可用於做一些準備工作
  • doInBackground(Params…params) 在線程池執行,在此方法中可以通過publishProgress方法類更新任務進度,publishProgress方法會調用onProgressUpdate方法,此方法最後還需將任務結果返回給onPostExecute方法
  • onProgressUpdate(Progress..values) 在主線程執行,任務進度發生改變時此方法會被調用
  • onPostExecute(Result result) 主線程執行,任務執行之後被調用,result參數是doInBackground方法的返回值

上面方法,正常執行順序是onPreExecute先執行,接着是doInBackground,最後纔是onPostExecute執行。 另外AsyncTask 還提供了onCancelled方法,同樣在主線程中執行,當異步任務被取消時,onCancelled方法會被調用,這時候onPostExecute方法則不會被調用

AsyncTask 使用注意

  1. AsyncTask 對象必須在主線程中創建
  2. execute方法必須在UI線程中調用
  3. 不要再程序中直接調用它的四個核心方法
  4. 一個AsyncTask 對象只能執行一次,即只能調用一次execute方法,否則會報運行時異常
  5. AsyncTask 在3.0及以後的版本中是採用一個線程來串行執行任務的,但是我們可以通過AsyncTask 的executeOnExecutor方法來並行執行任務
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    Button button1;

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


    private void findId(){
        button1 = findViewById(R.id.btn_1);
        button1.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
       if (v == button1){
           new MyAsyncTask("AsyncTask#1").
                   executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
           new MyAsyncTask("AsyncTask#2").
                   executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
           new MyAsyncTask("AsyncTask#3").
                   executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
           new MyAsyncTask("AsyncTask#4").
                   executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
           new MyAsyncTask("AsyncTask#5").
                   executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
       }
    }

    private static class MyAsyncTask extends AsyncTask<String,Integer,String>{
        private String mName = "AsyncTask";
        public MyAsyncTask(String mName){
            super();
            mName = mName;
        }

        @Override
        protected String doInBackground(String... strings) {

            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return mName;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Log.d("xj", s + "execute finish at : " +df.format(new Date()));
        }
    }
}

並行運行結果:可以看到他們的結束時間是一樣的

09-13 16:12:20.441 AsyncTaskexecute finish at : 2018-09-13 16:12:20
09-13 16:12:20.443 AsyncTaskexecute finish at : 2018-09-13 16:12:20
09-13 16:12:20.444 AsyncTaskexecute finish at : 2018-09-13 16:12:20
09-13 16:12:20.445 AsyncTaskexecute finish at : 2018-09-13 16:12:20
09-13 16:12:20.446 AsyncTaskexecute finish at : 2018-09-13 16:12:20

串行運行時,5個任務共耗時15s,且時間間隔爲3s

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