一、簡介
- Android 的UI都是由主線程繪制的
- 和其他大多數(shù)GUI庫一樣埂材,Android 的UI也是線程不安全的嘿棘,要想更新UI元素,一般必須在主線程中進行挨稿,否則會出現(xiàn)異常仇轻。
- Android的對此一般采用異步消息處理機制。
- AsyncTask使用線程池奶甘,所以比handler效率更高
二篷店、異步消息處理機制
//handler
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// super.handleMessage(msg);
String str = (String) msg.obj;
tv_status.setText(str);
//判斷當前函數(shù)是否在主線程中執(zhí)行
boolean result = Looper.getMainLooper() == Looper.myLooper();
Log.d(TAG, "handleMessage: "+result);
}
};
class myThread extends Thread{
@Override
public void run() {
// super.run();
try {
Thread.sleep(1000*6);
String str = "子線程消息";
Message message = new Message();
message.obj = str;
handler.sendMessage(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
-
Message
可以攜帶少量信息,在線程之間傳遞臭家,可以使用what疲陕、arg1、arg2钉赁、obj等字段攜帶數(shù)據(jù)蹄殃。 -
Handler
處理者,用于發(fā)送和處理消息你踩。sendMessage()方法發(fā)送消息诅岩,handleMessage()接收。 -
MessageQueue
消息隊列带膜,存放handler發(fā)送的消息吩谦,每個線程只有一個MessageQueue對象。 -
Looper
MessageQueue的管理者钱慢,Looper調用loop()方法逮京,進入無限循環(huán)卿堂,一發(fā)現(xiàn)MessageQueue中有消息束莫,就取出傳遞給handleMessage(),同樣每個線程只有一個Looper對象草描。
三览绿、AsyncTask
- 使用在代碼中做了詳細的說明
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private TextView tv_text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_text = (TextView) findViewById(R.id.tv_text);
//啟動任務
new DownloadTask().execute(10);
}
/**
* 三個泛型參數(shù):
* Params 需要傳入后臺任務的參數(shù),指定類型
* Progress 后臺任務執(zhí)行時進度穗慕,指定進度單位
* Result 執(zhí)行結果饿敲,指定返回類型
*/
class DownloadTask extends AsyncTask<Integer, Integer, Boolean> {
/**
* 后臺任務執(zhí)行前調用,一般用于初始化操作逛绵,比如顯示一個進度條對話框
*/
@Override
protected void onPreExecute() {
// super.onPreExecute();
tv_text.setText("準備顯示");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 方法中的所有代碼都在子線程中運行怀各,處理耗時操作,并返回執(zhí)行結果
*/
@Override
protected Boolean doInBackground(Integer... voids) {
for (int i = 0; i < voids[0]; i++){
try {
Thread.sleep(1000);
//傳遞進度
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return true;
}
/**
* 使用后臺任務傳遞的參數(shù)倔韭,在方法中對UI更新
*/
@Override
protected void onProgressUpdate(Integer... values) {
// super.onProgressUpdate(values);
//更新顯示
tv_text.setText(""+values[0]);
}
/**
* 后臺任務執(zhí)行完之后調用,并接受返回的參數(shù)瓢对,更新UI寿酌,比如提醒任務結束,關閉對話框等
*/
@Override
protected void onPostExecute(Boolean b) {
// super.onPostExecute(b);
tv_text.setText(""+b);
}
}
}
注:當當前的Activity退出后硕蛹,開啟的任務仍然會繼續(xù)執(zhí)行醇疼,所以,需要停止時就得重寫活動的銷毀方法法焰,在方法中停止