AsyncTask對比Thread加Handler

很多網友可能發現Android平臺很多應用使用的都是AsyncTask,而並非Thread和Handler去更新UI,這裏Android123給大家說下他們到底有什麼區別,我們平時應該使用哪種解決方案。從Android 1.5開始系統將AsyncTask引入到android.os包中,過去在很早1.1和1.0 SDK時其實官方將其命名爲UserTask,其內部是JDK 1.5開始新增的concurrent庫,做過J2EE的網友可能明白併發庫效率和強大性,比Java原始的Thread更靈活和強大,但對於輕量級的使用更爲佔用系統資源。Thread是Java早期爲實現多線程而設計的,比較簡單不支持concurrent中很多特性在同步和線程池類中需要自己去實現很多的東西,對於分佈式應用來說更需要自己寫調度代碼,而爲了Android UI的刷新Google引入了Handler和Looper機制,它們均基於消息實現,有事可能消息隊列阻塞或其他原因無法準確的使用。

  推薦大家使用AsyncTask代替Thread+Handler的方式,不僅調用上更爲簡單,經過實測更可靠一些,Google在Browser中大量使用了異步任務作爲處理耗時的I/O操作,比如下載文件、讀寫數據庫等等,它們在本質上都離不開消息,但是AsyncTask相比Thread加Handler更爲可靠,更易於維護,但AsyncTask缺點也是有的比如一旦線程開啓即dobackground方法執行後無法給線程發送消息,僅能通過預先設置好的標記來控制邏輯,當然可以通過線程的掛起等待標誌位的改變來通訊,對於某些應用Thread和Handler以及Looper可能更靈活。


這兩種異步處理方法中,其中AsyncTask這個類感覺使用比較簡單,就是實現其中幾個方法,onPreExecute()方法是在任務剛開始運行時執行的一些初始化操作,比如初始化一個進度條等等,然後就執行doInBackground()方法這裏面主要放業務操作,比如查詢數據庫等,在這個方法執行的時候會調用onProgressUpdate(),可以在這個方法中更新UI界面,最後是調用onPostExecute()方法,當得到業務結果後就可以在這個方法中返回給UI線程,也可以關閉一些執行這個業務時開的一些資源。大家可以看得出AsyncTask這個類是一個泛型類,這個類的三個參數以此對應doInBackground(String... params),onProgressUpdate(String... values),onPostExecute(String result)的參數,很形象的···如果不需要傳參和返回值,可以用Void代替。而doInBackground(String... params)方法的返回值也就是onPostExecute(String result)方法的參數值,因爲doInBackground方法執行後返回的值是在onPostExecute(String result)中處理的。


用handler方式處理需要知道與handler相關的幾個組件,Looper和Queue,其實Looper的作用就是把handler發送的消息放到Queue中,並把消息廣播給所有與這個Queue相關的handler,而Queue一般是主線程開啓的時候就給這個線程分配了一個,所以你要與UI主線程通信必須用於這個Queue相關聯的handler對象才行,一般handler對象在那個線程中創建的就與那個線程的queue關聯,所以在UI線程中創建的handler對象就與UI線程通訊,這樣我們就可以在子線程中發送消息給主線程,實現更新UI的功能。那主線程又是怎麼處理子線程發送的消息的呢?其實在生成handler對象的時候我們就要實現handler對象的handleMessage()方法這個方法就是主線程接受並處理子線程發送過來的消息的方法,從而實現 更新UI線程的功能。


簡單示例:

private Handler handler = new Handler() {
 
	@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case 1:
			adapter.notifyDataSetChanged();
		break;
		}
	}
};

public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	showContent();
}

private void showContent() {
	listView = (ListView) findViewById(R.id.journals_list_one);
	// MyTask myTask = new MyTask();
	// myTask.execute(null);
	new Thread() {
	 
	@Override
	public void run() {
		try {
			Thread.sleep(5000);
			loadData();
		} catch (InterruptedException e) {
		e.printStackTrace();
		}
	}}.start();
	adapter = new JournalListAdapter(this, data);
    listView.setAdapter(adapter);
}
 
/**
* 構造List列表數據
*/
private void loadData() {
	if (data.size() <= 40) {
		for (int i = 0; i < 10; i++) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("title", getString(R.string.title));
			map.put("desc", getString(R.string.content));
			data.add(map);
			Message message = handler.obtainMessage();
			message.what = 1;
			message.sendToTarget();
		}
	}
}
 
class MyTask extends AsyncTask<String, String, String> {
 
	private ProgressDialog progressBar;
 
	@Override
	protected void onPreExecute() {
		progressBar = new ProgressDialog(MainPageActivity.this);
		progressBar.setMessage("正在加載數據請稍後...");
		progressBar.setIndeterminate(true);
		progressBar.show();
		super.onPreExecute();
	}
	 
	@Override
	protected String doInBackground(String... params) {
		try {
			Thread.sleep(5000);
			loadData();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return null;
	}
	 
	@Override
	protected void onProgressUpdate(String... values) {
		super.onProgressUpdate(values);
		adapter.notifyDataSetChanged();
	}
	 
	@Override
	protected void onPostExecute(String result) {
		super.onPostExecute(result);
		progressBar.dismiss();
	}
 
}


發佈了9 篇原創文章 · 獲贊 9 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章