Handle與AsyncTask非同步載入資料
阿新 • • 發佈:2019-02-03
Handle通訊的簡單使用
Handle是在不同的執行緒中進行訊息傳遞的一種機制,或者你可以認為是一個能幫你實現這種功能的類。主要用於解決Android中子執行緒無法更新UI的問題,子執行緒將需要更新的資料通過Handle傳遞給UI執行緒,UI執行緒做更新,這樣就實現了子執行緒更新UI執行緒。
注意,本文不會講Handle的實現原理,不會將AsyncTask的機制框架,只是簡單的教你怎麼使用它們,如果你已經掌握了它們是如果使用的,這篇文章對你不會有太多的幫助
建立Handle
想要用Handle就少不了要建立一個Handle。不過需要注意的是,每個UI執行緒,就是那個Activity類,只能建立一個Handle。訊息是由哪個Handle發的,在UI執行緒中就必須要由哪個Handle處理,建立多了會出現找不到訊息的情況。所以,如果不是必須,儘量一個Activity只建立一個Handle。 建立的程式碼如下:注意,該類需要實現一個父類的方法,即handleMessage(),這個方法是你獲得訊息後,需要如何更新UI,是要在該方法內實現的,比如改變一下某個TextView的內容。其中的引數msg,就是你在子執行緒中要傳遞的訊息。
public Handler mHandle = new Handler(){
@Override
public void handleMessage(Message msg) {
textView.setText((String)msg.obj);
}
};
使用Handle
handle的使用是在子執行緒中使用,這就需要你將建立的handle宣告為全域性變數。而且在只能建立一個,一定不要在子執行緒中再建立一個。這樣傳遞的訊息在主執行緒的handle是不會處理的(就是找不到訊息,怎處理)。 程式碼如下:新的Thread是你的子執行緒,資料的更新等耗時操作都可以放到這裡來,Message是你需要傳送的訊息物件,可以通過new創建出來,也可以通過handle的方法建立,兩者區別不是太大。但是還是建議使用後者。 Message類有兩個常用的屬性,msg.what,是訊息的屬性,確定訊息的類別,比如網路請求,請求成功what = 200,失敗what = 404,這樣,在UI中就可以判斷,是什麼型別的訊息,做分別處理。第二個屬性是msg.obj,看名字就知道是一個Object物件,如果要傳遞複雜的訊息,比如List,等物件,就可以對該屬性賦值,然後在UI執行緒中強轉。就可以使用了。sendMessage(msg)是將訊息傳送出去。 順便說一下,如果你不需要傳送什麼訊息,僅僅是需要通知下UI執行緒,可以使用mHandle.sendEmptyMessage(int what);引數是訊息型別。
程式碼如下
public void changeText(){
new Thread(new Runnable() {
@Override
public void run() {
Message msg = mHandle.obtainMessage();
msg.what = 3;
msg.obj = "子執行緒改變";
mHandle.sendMessage(msg);
}
}).start();
}
AsyncTask 簡單使用
AsyncTack是一種非同步載入機制,一般用在ListView,下拉重新整理的ListView,當下拉時,載入的資料可以使用這種機制載入。
Asynctask 的建立
要使用AsyncTask時,需要建立一個類,並繼承AsyncTaskAsyncTask<Params, Progress, Result> 。這個類有幾個方法需要實現,有在後臺載入資料的方法,有在UI中執行更新UI的方法。AsyncTask類有三個泛型,Params是指在後臺執行的操作需要引數時的引數型別。Progress是當前後臺執行的任務,即載入資料的進度,Result是後臺任務執行結束後返回的結果集型別。
繼承該類後需要實現幾個方法,必須要實現一個,根據你需要的功能再實現其他的。
doInBackground() 這個是你必須要實現的方法,用於資料載入等耗時操作,該方法不能訪問UI執行緒。該方法在執行完onPreExecute()方法後執行。
onPreExecute()該方法是在UI執行緒中執行的,一般是在執行doInBackground() 前對UI進行的一些操。不是必須要實現的。
onPostExecute(Result) 該方法是在UI執行緒中執行的,是在執行完doInBackground() 方法後執行的,傳遞的引數是doInBackground() 返回的結果集。
onProgressUpdate(Progress) 方法是在UI中執行的,是將後臺任務的進度更新到UI中,比如更新進度條之類的。
注意:如果需要使用onProgressUpdate() 方法更新進度,就必須在doInBackground()方法中將進度傳遞出去,這就要用到publishProgress(Progress)方法,該方法是將當前進度傳遞出去
忘了說了,如果你不需要這些範型,可以用 Void 代替,對,你沒看錯,是大寫的’V’
程式碼如下:
public class DownLoadTask extends AsyncTask<String, Integer, String> {
/**
* 在後臺執行的方法,獲取資源
* @param params
* @return
*/
@Override
protected String doInBackground(String... params) {
//在doInBackground對外公佈任務進度,類似sendMessage
publishProgress(i);
}
return "";
}
/**
* 主執行緒在執行doInBackground方法之前執行的方法
* 該方法在主執行緒中執行
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* 主執行緒在執行doInBackground之後執行該方法
*
* @param s doInBackground 方法的返回結果
*/
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
textView.setText(s);
}
/**
* 用於接收 publishProgress 公佈的引數執行在主執行緒中
* @param values publishProgress 的引數
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
}
AsyncTask使用
AsyncTask的使用非常簡單,建立你剛剛建立的那個繼承AsyncTask的類物件,然後呼叫 execute(Params)方法即可
程式碼如下:
DownLoadTask down = new DownLoadTask();
//如果你的Params是Void就別傳引數了
down.execute("www.baidu.com");
Handle與AsyncTask 簡單對比
相同點
Handle與AsyncTask 都是為了解決非同步載入的問題的。用於將子執行緒中載入的資料,傳遞到UI執行緒中。都是為了在不阻塞UI執行緒的同時執行其他執行緒。
Handle
handle使用簡單,在處理多個程序的通訊,多種訊息的處理時優於AsyncTask,容易理解,它是將訊息從子執行緒傳送到UI執行緒中去,在UI執行緒中做處理。是Android中執行緒間通訊的主流使用方法。
AsyncTask
AsyncTask是一種非同步載入的機制,是將資料載入,UI的更新封裝到一個類中,然後將這些介面暴露出來,讓你去實現。理解起來比較不容易,使用時比較簡單,適用與簡單的資料載入,在面對多個執行緒通訊時可能有些不足