1. 程式人生 > >Handler和AsyncTask非同步方式的實現

Handler和AsyncTask非同步方式的實現

1.Handler非同步方式的實現

在Handler 非同步實現時,涉及到 Handler, Looper, Message,Thread四個物件,實現非同步的流程是主執行緒啟動Thread(子執行緒)執行並生成 Looper獲取Message並傳遞給Handler逐個獲取Looper中的Message,並進行UI變更。Handler可以分發Message物件和Runnable物件到主執行緒中,每個Handler例項都會繫結到他建立的執行緒中。

Handler中分發訊息的一些辦法
handler.post(Runnable );將Runnable直接新增入佇列
handler.postDelayed(Runnable, long)延遲一定時間後,將Runnable新增入佇列
handler.postAtTime(Runnable,long)定時將Runnable新增入佇列
終止執行緒:handler.removeCallbacks(thread);將Runnable從Runnable佇列中取出

public class HandlerActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView mText1;
    private Button mBtn1;
    private static final int UPDATE_TEXT = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.handler_activity);
        mText1 = (TextView)findViewById(R.id.text1);
        mBtn1 = (Button)findViewById(R.id.button1);
        mBtn1.setOnClickListener(this);

    }
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what){
                case UPDATE_TEXT:
                    mText1.setText("Bye");
                    break;
                default:
                    break;
            }
        }
    };
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.button1:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Message message = new Message();
                        message.what = UPDATE_TEXT;
                        handler.sendMessage(message);
                    }
                }).start();
                break;
            default:
                break;
        }

    }
}

2.AsyncTask非同步方式的實現

AsyncTask定義了三種泛型型別 Params,Progress和Result。

①Params 啟動任務執行的輸入引數,比如HTTP請求的URL。
②Progress 後臺任務執行的百分比。
③Result 後臺執行任務最終返回的結果,比如String。

AsyncTask的四個重要方法:
①onPreExecute(),在UI執行緒中執行,它會在非同步任務開始前執行,一般用來設定任務引數;
②doInBackground, 最重要的方法,在子執行緒中執行(事實上,只有它在子執行緒中執行,其他方法都在UI執行緒中執行)。當onPreExecute結束後,本方法立刻執行,它用來進行後臺的耗時計算,非同步任務的引數會被傳給它,執行完成的結果會被送給第四步;執行途中,它還可以呼叫publishProgress 方法來通知UI執行緒當前執行的進度;
③onProgressUpdate, 當publishProgress 被呼叫後,它在UI執行緒中執行,重新整理任務進度,一般用來重新整理進度條等UI部件;
④onPostExecute, 當後臺的非同步任務完成後,它會在UI執行緒中被呼叫,並獲取非同步任務執行完成的結果。

public class MainActivity extends AppCompatActivity {

    private TextView mText;
    private Button mBtn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mText = (TextView)findViewById(R.id.text);
        mBtn = (Button)findViewById(R.id.button);
        mBtn.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View view) {
                update();
            }
        });
    }

    private void update() {
        DownloadTask downloadTask = new DownloadTask(this);
        downloadTask.execute();
    }
    public class DownloadTask extends AsyncTask<Void,Integer,Boolean> {
        private Context context;
        DownloadTask(Context context) {
            this.context = context;
        }
        @Override
        protected void onPreExecute(){
            Toast.makeText(context,"開始執行",Toast.LENGTH_SHORT).show();
        }
        @Override
        protected Boolean doInBackground(Void... params){
            int i = 0;
            try{
                while(true){
                    i++;
                    publishProgress(i);
                    try{
                        Thread.sleep(100);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    if(i >= 100){
                        break;
                    }
                }
            }catch (Exception e){
                return  false;
            }
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            mBtn.setText("下載完成");
            mBtn.setEnabled(false);
            Toast.makeText(context,"執行完畢",Toast.LENGTH_SHORT).show();
        }
        @Override
        protected void onProgressUpdate(Integer... values) {
            //progressBar.setProgress(values[0]);
            mText.setText("下載中"+values[0]+"%");
            //  mText.setText("Hello");
        }

    }

}