亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android中AsyncTask與handler用法實例分析

2020-04-11 11:20:27
字體:
來源:轉載
供稿:網友

本文實例講述了Android中AsyncTask與handler用法。分享給大家供大家參考,具體如下:

首先,我們得明確下一個概念,什么是UI線程。顧名思義,ui線程就是管理著用戶界面的那個線程!

android的ui線程操作并不是安全的,并且和用戶直接進行界面交互的操作都必須在ui線程中進行才可以。這種模式叫做單線程模式。

我們在單線程模式下編程一定要注意:不要阻塞ui線程、確保只在ui線程中訪問ui組件

當我們要執行一個復雜耗時的算法并且最終要將計算結果反映到ui上時,我們會發現,我們根本沒辦法同時保證上面的兩點要求;我們肯定會想到開啟一個新的線程,讓這個復雜耗時的任務到后臺去執行,但是執行完畢了呢?我們發現,我們無法再與ui進行交互了。
為了解決這種情況,android為我們提供了很多辦法。

1)、handler和message機制:通過顯示的拋出、捕獲消息與ui進行交互;

2)、Activity.runOnUiThread(Runnable):如果當前線程為ui線程,則立即執行;否則,將參數中的線程操作放入到ui線程的事件隊列中,等待執行。

3)、View.post(Runnable):將操作放入到message隊列中,如果放入成功,該操作將會在ui線程中執行,并返回true,否則返回false

4)、View.postDelayed(Runnable, long)跟第三條基本一樣,只不過添加了一個延遲時間。

5)、android1.5以后為我們提供了一個工具類來搞定這個問題AsyncTask.

AsyncTask是抽象類,定義了三種泛型類型 Params,Progress,Result。

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

用程序調用,開發者需要做的就是實現這些方法。

1) 子類化AsyncTask
2) 實現AsyncTask中定義的下面一個或幾個方法

onPreExecute(),該方法將在執行實際的后臺操作前被UI thread調用??梢栽谠摲椒ㄖ凶鲆恍蕚涔ぷ鳎缭诮缑嫔巷@示一個進度條。
doInBackground(Params…),將在onPreExecute 方法執行后馬上執行,該方法運行在后臺線程中。這里將主要負責執行那些很耗時的后臺計算工作??梢哉{用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
onProgressUpdate(Progress…),在publishProgress方法被調用后,UI thread將調用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。
onPostExecute(Result),在doInBackground 執行完成后,onPostExecute 方法將被UI thread調用,后臺的計算結果將通過該方法傳遞到UI thread.

為了正確的使用AsyncTask類,以下是幾條必須遵守的準則:

1) Task的實例必須在UI thread中創建
2) execute方法必須在UI thread中調用
3) 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params…), onProgressUpdate(Progress…)這幾個方法
4) 該task只能被執行一次,否則多次調用時將會出現異常

package cn.com.chenzheng_java; import android.os.AsyncTask; /**  *  * @author chenzheng_java  * @description 異步任務AcyncTask示例  *    */ public class MyAsyncTask extends AsyncTask<String, Integer, Object> {  /**  * 該方法由ui線程進行調用,用戶可以在這里盡情的訪問ui組件。  * 很多時候,我們會在這里顯示一個進度條啥的,以示后臺正在  * 執行某項功能。  */  @Override  protected void onPreExecute() {  super.onPreExecute();  }  /**  * 該方法由后臺進程進行調用,進行主要的耗時的那些計算。  * 該方法在onPreExecute方法之后進行調用。當然在執行過程中  * 我們可以每隔多少秒就調用一次publishProgress方法,更新  * 進度信息  */  @Override  protected Object doInBackground(String... params) {  return null;  }  /**  * doInBackground中調用了publishProgress之后,ui線程就會  * 調用該方法。你可以在這里動態的改變進度條的進度,讓用戶知道  * 當前的進度。  */  @Override  protected void onProgressUpdate(Integer... values) {  super.onProgressUpdate(values);  }  /**  * 當doInBackground執行完畢之后,由ui線程調用??梢栽谶@里  * 返回我們計算的最終結果給用戶。  */  @Override  protected void onPostExecute(Object result) {  super.onPostExecute(result);  } }

下面介紹最本質的多線程:hanlder和message機制:

為何需要多線程:

在日常應用中,我們通常需要處理一些“后臺,用戶不可見”的操作,例如說,我們需要下載一個音樂,要是你的應用必須等用戶下載完成之后才可以進行別的操作,那肯定讓用戶非常的不爽。這時候,我們通常的做法是,讓這些操作去后臺執行,然后等后臺執行完畢之后,再給用戶彈出相應的提示信息。這時候,我們就需要使用多線程機制,然后通過創建一個新的線程來執行這些操作。

明白了,實現需求,我們就準備著手實現了。但是,經過進一步的了解,我們悲劇的發現,android中的線程機制是,只能在UI線程中和用戶進行交互。當我們創建了一個新線程,執行了一些后臺操作,執行完成之后,我們想要給用戶彈出對話框以確認,但是卻悲劇的發現,我們根本無法返回UI主線程了。(UI線程就是你當前看到的這些交互界面所屬的線程)。

這時候,我們如果想要實現這些功能,我們就需要一個android為我們提供的handler和message機制。

先講解下編程機制:

我們通常在UI線程中創建一個handler,handler相當于一個處理器,它主要負責處理和綁定到該handler的線程中的message。每一個handler都必須關聯一個looper,并且兩者是一一對應的,注意,這點很重要哦!此外,looper負責從其內部的messageQueue中拿出一個個的message給handler進行處理。因為我們這里handler是在UI線程中實現的,所以經過這么一個handler、message機制,我們就可以回到UI線程中了。

handler:處理后臺進程返回數據的工作人員。
message:后臺進程返回的數據,里面可以存儲bundle等數據格式
messageQueue:是線程對應looper的一部分,負責存儲從后臺進程中拋回的和當前handler綁定的message,是一個隊列。
looper:looper相當于一個messageQueue的管理人員,它會不停的循環的遍歷隊列,然后將符合條件的message一個個的拿出來交給handler進行處理。

注意,handler是在UI線程中聲明的,如果我們直接用類似代碼執行一個線程的話,實際上并沒有創建一個新的線程,因為handler已經跟默認的UI線程中的looper綁定了。

如果有興趣的話,可以去看下Handler的默認空構造函數便知道原因了,里面直接綁定了當前UI線程的looper。

下面給出一個比較簡單,并且實用的實例。

public class MainActivity extends Activity implements OnClickListener {   private Button btnTXT;   private TextView tvTXT;   private StringBuffer returnMsg;   @Override   public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     btnTXT = (Button)findViewById(R.id.btnTXT);     tvTXT = (TextView)findViewById(R.id.tvTXT);     btnTXT.setOnClickListener(this);       }   @Override   public void onClick(View v) {     returnMsg = new StringBuffer();     // 創建一個包含Looper的線程,這里如果沒有HandlerThread的調用,會直接將后邊的MyRunnable放到UI線程隊列(myHandler.post(new MyRunnable()))     HandlerThread handlerThread = new HandlerThread("handler_thread");     handlerThread.start();   // 啟動自定義處理線程     myHandler = new MyHandler(handlerThread.getLooper());    // 將handler綁定到新線程      myHandler.post(new MyRunnable());    // 在新線程中執行任務    }   /** 主線程Handler,可以與UI控件交互 */   Handler mainHanlder = new Handler(){     @Override     public void handleMessage(Message msg) {       if(msg.what == 0) {         tvTXT.setText(returnMsg.toString());  // 與主線程控件打交道(直接訪問)       }     }   };   /** 構造Hanlder,不可與UI控件直接交互 */   private MyHandler myHandler = null;   private class MyHandler extends Handler{     /**      * 使用默認的構造函數,會將handler綁定當前UI線程的looper。      * 如果想使用多線程這里是不能使用默認的構造方法的。      */      public MyHandler(){       super();     }     /** 構造函數,自定義looper */     public MyHandler(Looper looper) {       super(looper);     }     // 處理具體的message消息,繼承自父類的方法     @Override     public void handleMessage(Message msg) {       int what = msg.what;         Bundle bundle = (Bundle)msg.obj;      // 提取bundle中的信息       String name = bundle.getString("name");       String sex = bundle.getString("sex");       boolean marry = bundle.getBoolean("marray");       int age = bundle.getInt("age");       StringBuffer strBuf = new StringBuffer();    // 拼接bundle信息       strBuf.append("what = ").append(what).append("/n/n");       strBuf.append("name = ").append(name).append("/n");       strBuf.append("sex = ").append(sex).append("/n");       strBuf.append("marry = ").append(marry).append("/n");       strBuf.append("age = ").append(age).append("/n/n");       strBuf.append("http://blog.csdn.net/sunboy_2050");       returnMsg = returnMsg.append(strBuf);  // 保存要顯示的結果       mainHanlder.sendEmptyMessage(0);    // 向主線程mainHanlder發送消息,與UI控件交互顯示結果       super.handleMessage(msg);     }   }   // 構造Runnable,處理后臺業務邏輯,如下載   private class MyRunnable implements Runnable{     @Override     public void run() {       try {         Message msg = Message.obtain(myHandler);  // 捕獲myHandler消息        msg.what = 10;         Bundle bundle = new Bundle();        // 封裝bundle信息         bundle.putString("name", "yanggang");         bundle.putString("sex", "pure boy");         bundle.putBoolean("marry", false);         bundle.putInt("age", 18);         msg.obj = bundle;         long thID = Thread.currentThread().getId();         returnMsg.append(thID).append(" : send msg start...").append("/n");         msg.sendToTarget();   // 向myHandler發送消息         Thread.sleep(3000);       } catch (Exception e) {         Log.i("", "Runnable send msg error...");         e.printStackTrace();       }     }   } }

運行結果:

完整實例代碼代碼點擊此處本站下載。

希望本文所述對大家Android程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
伊是香蕉大人久久| 亚洲图片欧洲图片av| 久久精品人人做人人爽| 中文字幕精品久久久久| 亚洲一二三在线| 久久影院资源网| 欧美日韩精品在线视频| 精品视频在线观看日韩| 欧美视频免费在线观看| 久久久97精品| 91久久精品国产91久久| 最近2019中文字幕第三页视频| 日韩av电影在线播放| 亚洲韩国欧洲国产日产av| 色yeye香蕉凹凸一区二区av| 97超级碰碰碰久久久| 日韩免费不卡av| 国产91网红主播在线观看| 国产福利精品在线| 精品久久久久久国产91| 亚洲综合一区二区不卡| 91精品国产91久久久久久不卡| 日韩精品视频免费| 日韩高清不卡av| 亚洲毛片在线免费观看| 欧美激情小视频| 色婷婷成人综合| 国产在线999| 欧美丰满少妇xxxxx做受| 亚洲国产欧美久久| 欧美大片欧美激情性色a∨久久| 精品一区精品二区| 国产精品自产拍在线观看中文| 久久综合免费视频影院| 国产一区二区在线免费| 综合久久五月天| 久久久久久一区二区三区| 久久不射电影网| 欧美在线视频网站| 国内伊人久久久久久网站视频| 91精品国产高清久久久久久| 中文字幕亚洲第一| 欧美性videos高清精品| 欧美剧在线观看| 亚洲国产私拍精品国模在线观看| 国产一区二区三区精品久久久| 亚洲男人天堂2024| 欧洲中文字幕国产精品| 亚洲伦理中文字幕| 国产久一一精品| 亚洲欧洲日产国码av系列天堂| 国产亚洲免费的视频看| 精品久久久久久久中文字幕| 精品亚洲一区二区三区在线播放| 久久久久久成人精品| 国内免费精品永久在线视频| 久久成人精品电影| 欧美一级淫片播放口| 欧美成人免费大片| 亚洲综合日韩中文字幕v在线| 一区二区三区四区精品| 91亚洲va在线va天堂va国| 8x拔播拔播x8国产精品| 日本精品在线视频| 丝袜亚洲另类欧美重口| 国产精品久久久久一区二区| 美女黄色丝袜一区| 亚洲视频欧美视频| 欧美大片免费观看在线观看网站推荐| 欧美高清无遮挡| 亚洲自拍偷拍网址| 精品电影在线观看| 国产成人啪精品视频免费网| 国产一区二区黄| 国产盗摄xxxx视频xxx69| 中文字幕久热精品在线视频| 亚洲自拍偷拍区| 55夜色66夜色国产精品视频| 久久躁狠狠躁夜夜爽| 综合国产在线观看| 91精品久久久久久久久久久| 69国产精品成人在线播放| 国产欧美 在线欧美| 国产精品一区二区av影院萌芽| 国内外成人免费激情在线视频网站| 97久久超碰福利国产精品…| 欧美电影第一页| 91精品国产91久久久| 欧美激情在线狂野欧美精品| 91免费高清视频| 国产精品尤物福利片在线观看| 欧美性猛交xxxx免费看| 久久99国产综合精品女同| 黑人巨大精品欧美一区二区免费| 精品国产老师黑色丝袜高跟鞋| 亚洲精品视频免费| 热99精品里视频精品| 亚洲老头老太hd| 久久国产视频网站| 97在线视频免费播放| 亚洲第一av网站| 欧美与欧洲交xxxx免费观看| 国产欧美在线观看| 热re91久久精品国99热蜜臀| 欧美成人免费全部观看天天性色| 国产成人在线一区二区| 在线播放精品一区二区三区| 国产成人精品优优av| 日韩电影免费观看在线观看| 欧美韩国理论所午夜片917电影| 国产日韩在线视频| 高清欧美性猛交xxxx黑人猛交| 欧美性猛交xxxx偷拍洗澡| 91在线视频免费| 日韩在线小视频| 中文字幕视频在线免费欧美日韩综合在线看| 国产精品一二区| 一区二区三区动漫| 欧美激情乱人伦一区| 欧美一级免费视频| 国产一区二区三区18| 黑人巨大精品欧美一区二区| 日韩激情av在线免费观看| 国产一区二区三区精品久久久| 最近2019好看的中文字幕免费| 国产精品老女人视频| 亚洲精品国产精品国自产在线| 91国内精品久久| 黑人狂躁日本妞一区二区三区| 亚洲欧美成人在线| 亚洲在线视频福利| 中文字幕视频在线免费欧美日韩综合在线看| 日韩www在线| 久久亚洲私人国产精品va| 亚洲男人第一网站| 欧美乱大交xxxxx| 亚洲一区二区中文字幕| 富二代精品短视频| 欧美午夜宅男影院在线观看| 国产一区二区三区直播精品电影| 国内精品久久久| 国产一区视频在线| 国产欧美精品一区二区三区-老狼| 成人精品视频久久久久| 久久激情五月丁香伊人| 91精品视频观看| 久久精品免费电影| 久久久久久香蕉网| 亚洲欧美中文日韩在线v日本| 国产不卡av在线免费观看| 国产精品自拍偷拍| 伊人久久久久久久久久久| 国产97在线观看| 国产视频精品免费播放| 色综合久久88| 日韩精品在线观看网站| 久久91亚洲精品中文字幕奶水| 91av在线播放视频| 日本道色综合久久影院| 69久久夜色精品国产69| 中文字幕亚洲欧美在线| 欧美大尺度激情区在线播放| 91夜夜揉人人捏人人添红杏| 中文字幕成人精品久久不卡|