国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

android異步機制

2019-11-06 09:41:54
字體:
供稿:網(wǎng)友

概述:

異步消息處理線程啟動后會進入一個無限的循環(huán)體之中,每循環(huán)一次,從其內(nèi)部的消息隊列中取出一個消息,然后回調(diào)相應的消息處理函數(shù),執(zhí)行完成一個消息后則繼續(xù)循環(huán)。若消息隊列為空,線程則會阻塞等待。

handler機制

一、使用的優(yōu)點:

          結構清晰,功能定義明確          對于多個后臺任務時,簡單,清晰        使用的缺點:

          在單個后臺異步處理時,顯得代碼過多,結構過于復雜(相對性)

二、Handler 、 Looper 、Message 這三者的關系總結:1、首先Looper.PRepare()在本線程中保存一個Looper實例,然后該實例中保存一個MessageQueue對象;因為Looper.prepare()在一個線程中只能調(diào)用一次,所以MessageQueue在一個線程中只會存在一個。2、Looper.loop()會讓當前線程進入一個無限循環(huán),不端從MessageQueue的實例中讀取消息,然后回調(diào)msg.target.dispatchMessage(msg)方法。3、Handler的構造方法,會首先得到當前線程中保存的Looper實例,進而與Looper實例中的MessageQueue想關聯(lián)。4、Handler的sendMessage方法,會給msg的target賦值為handler自身,然后加入MessageQueue中。5、在構造Handler實例時,我們會重寫handleMessage方法,也就是msg.target.dispatchMessage(msg)最終調(diào)用的方法。好了,總結完成,大家可能還會問,那么在Activity中,我們并沒有顯示的調(diào)用Looper.prepare()和Looper.loop()方法,為啥Handler可以成功創(chuàng)建呢,這是因為在Activity的啟動代碼中,已經(jīng)在當前UI線程調(diào)用了Looper.prepare()和Looper.loop()方法。

三、Looper主要作用:        與當前線程綁定,保證一個線程只會有一個Looper實例,同時一個Looper實例也只有一個MessageQueue。        loop()方法,不斷從MessageQueue中去取消息,交給消息的target屬性的dispatchMessage去處理。        private Looper(boolean quitAllowed) {                  mQueue = new MessageQueue(quitAllowed);                  mRun = true;                  mThread = Thread.currentThread();          }          在構造方法中,創(chuàng)建了一個MessageQueue(消息隊列)。        public static final void prepare() {              if (sThreadLocal.get() != null) {                  throw new RuntimeException("Only one Looper may be created per thread");              }              sThreadLocal.set(new Looper(true));          }          這也就說明了Looper.prepare()方法不能被調(diào)用兩次,同時也保證了一個線程中只有一個Looper實例。

四、在子線程中創(chuàng)建handler:

其實Handler不僅可以更新UI,你完全可以在一個子線程中去創(chuàng)建一個Handler,然后使用這個handler實例在任何其他線程中發(fā)送消息,最終處理消息的代碼都會在你創(chuàng)建Handler實例的線程中運行。    new Thread(){          private Handler handler;          public void run()          {              Looper.prepare();               handler = new Handler()              {                  public void handleMessage(android.os.Message msg)                  {                      Log.e("TAG",Thread.currentThread().getName());                  };              };

android.os.AsyncTask

一、使用的優(yōu)點: 簡單,快捷 、過程可控              使用的缺點:在使用多個異步操作和并需要進行Ui變更時,就變得復雜起來.

二、主要方法介紹:

     doInBackground(Params…)  后臺執(zhí)行,比較耗時的操作都可以放在這里。注意這里不能直接操作UI。此方法在后臺線程執(zhí)行,完成任務的主要工作,通常需要較長的時間。在執(zhí)行過程中可以調(diào)用publicProgress(Progress…)來更新任務的進度。    onPostExecute(Result)  相當于Handler 處理UI的方式,在這里面可以使用在doInBackground 得到的結果處理操作UI。 此方法在主線程執(zhí)行,任務執(zhí)行的結果作為此方法的參數(shù)返回    onProgressUpdate(Progress…)   可以使用進度條增加用戶體驗度。 此方法在主線程執(zhí)行,用于顯示任務執(zhí)行的進度。    onPreExecute() 這里是最終用戶調(diào)用Excute時的接口,當任務執(zhí)行之前開始調(diào)用此方法,可以在這里顯示進度對話框。    onCancelled()  用戶調(diào)用取消時,要做的操作

三、使用AsyncTask類,以下是幾條必須遵守的準則:    Task的實例必須在UI thread中創(chuàng)建;    execute方法必須在UI thread中調(diào)用;    不要手動的調(diào)用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法;    該task只能被執(zhí)行一次,否則多次調(diào)用時將會出現(xiàn)異常;

四、實例說明:

創(chuàng)建一個asynctask:

/** * 執(zhí)行的順序: *      onPreExecute() ---> doInBackground() ---> publishProgress() ---> onProgressUpdate() ....---> onPostExecute() * ...表示:publishProgress() ---> onProgressUpdate() */public class MyAsyncTask extends AsyncTask<Integer , Object , String>{    private TextView tv;    public MyAsyncTask(TextView textView){        Log.e(TAG , "調(diào)用到了構造函數(shù)");        this.tv = textView;    }    /**     * 這里的Integer參數(shù)對應AsyncTask中的第一個參數(shù)     * 這里的String返回值對應AsyncTask的第三個參數(shù)     * 該方法并不運行在UI線程當中,主要用于異步操作,所有在該方法中不能對UI當中的空間進行設置和修改     * 但是可以調(diào)用publishProgress方法觸發(fā)onProgressUpdate對UI進行操作     */    @Override    protected String doInBackground(Integer[] params) {        int i;        for (i = 0; i <= 100; i++) {            publishProgress(i); //會將這個值傳遞給onProgressUpdate()方法            SystemClock.sleep(1000);        }        Log.e(TAG , "調(diào)用到了doInBackground  i = " + i );        return i + "";    }    /**     * 這里是最終用戶調(diào)用Excute時的接口,當任務執(zhí)行之前開始調(diào)用此方法,可以在這里顯示進度對話框。     */    @Override    protected void onPreExecute() {        Log.e(TAG , "調(diào)用到了onPreExecute");        super.onPreExecute();        tv.setText("開始執(zhí)行異步操作了");    }    /**     * 這里的String參數(shù)對應AsyncTask中的第三個參數(shù)(也就是接收doInBackground的返回值)     * 在doInBackground方法執(zhí)行結束之后在運行,并且運行在UI線程當中 可以對UI空間進行設置     */    @Override    protected void onPostExecute(String result) {        Log.e(TAG , "調(diào)用到了onPostExecute result = " + result );        super.onPostExecute(result);        tv.setText(result);    }    /**     * 這里的Intege參數(shù)對應AsyncTask中的第二個參數(shù)     * 在doInBackground方法當中,,每次調(diào)用publishProgress方法都會觸發(fā)onProgressUpdate執(zhí)行     * onProgressUpdate是在UI線程中執(zhí)行,所有可以對UI空間進行操作     */    @Override    protected void onProgressUpdate(Object... values) {        Log.e(TAG , "調(diào)用到了onProgressUpdate value = " + values);        super.onProgressUpdate(values);        tv.setText(values[0] + "");    }}

執(zhí)行異步操作:

MyAsyncTask task = new MyAsyncTask(tv_show);task.execute();


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 大同市| 南澳县| 上蔡县| 沈丘县| 禹城市| 连南| 山东省| 肥西县| 正镶白旗| 石屏县| 乌拉特前旗| 邛崃市| 鄂尔多斯市| 洛南县| 安泽县| 平阴县| 敖汉旗| 辽阳市| 剑河县| 汉阴县| 祁连县| 沙洋县| 额尔古纳市| 阿合奇县| 丹江口市| 宁南县| 桂阳县| 丹凤县| 婺源县| 巨鹿县| 茌平县| 江门市| 嘉鱼县| 上栗县| 鄱阳县| 精河县| 安远县| 绥阳县| 中阳县| 安乡县| 桃园县|