編輯:關於Android編程
看了前面的文章我們知道請求網絡的幾種方式:
1.使用TCP協議和URL進行網絡編程
a)基於TCP協議:ServerSocket,Socket
b)基於URL:URL 和 URLConnection
2.使用Http協議進行網絡編程
a)HttpURLConnection
b)HttpClient
我們知道這些網絡請求都應該在子線程中,不能在主線程中(因為耗時操作會阻塞主線程,造成ANR)。但是在子線程中請求的數據需要傳遞給主線程來更新UI。我們經常使用的一種方式應該是借助於 Handler機制。
是的,這是一種方式,今天我們來講解另外一種方式來更新UI—–AsyncTask(異步加載).
這個AsyncTask(異步加載)將訪問網絡和更新UI放在了一起,其實究其根源也是使用了Handler機制,只不過幫我們把Handler機制和訪問網絡封裝起來罷了。
那這兩種方式做個比較:
Handler VS AsyncTask
AsyncTask實現的原理:AsyncTask的本質是一個線程池,所有提交的異步任務都會在這個線程池中的工作線程內執行,當工作線程需要跟UI線程交互時,工作線程會通過向在UI線程創建的Handler傳遞消息的方式,調用相關的回調函數,從而實現UI界面的更新。
優點:
①簡單快捷
②過程可控
缺點:
在使用多個異步操作和並需要進行Ui變更時,就變得復雜起來.
Handler實現的原理:在Handler 異步實現時,涉及到 Handler, Looper, Message,Thread四個對象,實現異步的流程是主線程啟動Thread(子線程)àthread(子線程)運行並生成Message- àLooper獲取Message並傳遞給HandleràHandler逐個獲取Looper中的Message,並進行UI變更。
優點:
①結構清晰,功能定義明確
②對於多個後台任務時,簡單清晰
缺點:
在單個後台異步處理時,顯得代碼過多,結構過於復雜(相對性)
既然這樣我們就來講下AsyncTask(異步加載)吧。
AsyncTask定義了三種泛型類型 Params,Progress和Result。(也是可以指定為空的,如 AsyncTask
- Params 啟動任務執行的輸入參數。比如Http請求的URL
- Progress 後台任務執行的進度百分比。
- Result 後台執行任務最終返回的結果。比如String
使用過AsyncTask 的同學都知道一個異步加載數據最少要重寫以下這兩個方法:
doInBackground(Params…)
說明:
doInBackground有返回值,並且返回值由Result決定
參數列表首先是一個可變長參數,是由Params決定
執行時機:在onPreExecute()方法之後立馬執行
作用:主要負責執行那些很耗時的後台操作,在後台執行
跟之前在子線程寫的代碼是一樣的
在執行過程中可以調用publicProgress(Progress…)來更新任務的進度。
onPostExecute(Result)
說明:
onPostExecute(Result)沒有返回值
參數是doInBackground的返回值
執行時機:doInBackground執行完
相當於Handler 處理UI的方式
此方法在主線程執行
有必要的話你還得重寫以下這三個方法,但不是必須的:
onProgressUpdate(Progress…)
說明:
沒返回值,不會主動回調,而是需要publishProgress()去間接調用
onProgressUpdate的參數由Progress決定
執行時機:這個函數在doInBackground調用publishProgress()之後
作用:在界面上展示任務的進度情況,可以使用進度條增加用戶體驗度
跟之前handleMessesg中的代碼一樣
此方法在主線程執行
onPreExecute()
說明:
沒有返回值也沒有參數
執行時機:這裡是最終用戶調用Excute時的接口,當任務執行之前開始調用此方法
作用:可以在該方法中做一些准備工作及一些初始化的操作,這個方法可以不用實現
onCancelled() 用戶調用取消時,要做的操作
使用AsyncTask類,以下是幾條必須遵守的准則:
Task的實例必須在UI thread中創建
execute方法必須在UI thread中調用
不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params…), onProgressUpdate(Progress…)這幾個方法;
該task只能被執行一次,否則多次調用時將會出現異常
流程:
實例-excute(Params)-doInBackground的參數
Progress-publishProgress的參數-onProgressUpdate的參數
Result-doInBackground返回值-onPostExcute的參數
這裡舉個例子說明一下:
假設Params 為Integer
Progress 為Integer
Result 為String
則AsyncTask
示意圖:
這幅圖可以知道各個方法的執行順序,以及各個參數的來源和流向。這應該很清楚了,我就不解釋了。
這裡寫個示例代碼模擬下:
效果:
首先一個異步的下載的類DownloadTask.java
doInBackground中用個fZ喎?/kf/ware/vc/" target="_blank" class="keylink">vctGtu7fAtMSjxOK6xMqxstnX96GjPGJyIC8+DQqyzsr9tKvBy9K7uPbLr8Pfyv08L3A+DQo8cHJlIGNsYXNzPQ=="brush:java;">
/**
* 流程:
* 實例-excute(Params)-doInBackground的參數
* Progress-publishProgress的參數-onProgressUpdate的參數
* Result-doInBackground返回值-onPostExcute的參數
*/
/**
* 三個泛型 第一個參數Params:後台處理時需要傳遞過來的數據類型,比如URL ---String 第二個參數Progress:進度百分比
* 第三個參數Result:後台處理完成返回數據類型
*
* @author Administrator
*
*/
public class DownloadTask extends AsyncTask
activity_main.xml
MainActivity.java
public class MainActivity extends Activity {
private ProgressBar pb;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pb = (ProgressBar) findViewById(R.id.pb);
tv = (TextView) findViewById(R.id.tv);
}
public void onClick(View view) {
DownloadTask downloadTask = new DownloadTask(tv, pb);
downloadTask.execute(1000);
}
}
看起來感覺很復雜,但是學會了用起來是很方便的。小伙伴趕緊試試吧。
ImageView有scaleType屬性可以縮放圖片,讓圖片鋪滿屏幕寬度,但是會出現壓縮或裁剪的情況。ImageView的scaleType的屬性分別是ma
網易新聞看起來很簡潔,左邊是一張圖片,右邊是一些文字信息,這樣的排版是十分常見的,給人的感覺就是簡潔明了,下面通過解析網絡json數據並展示到ListView上,來實現同
應用小掛件(也叫做窗口小掛件)在android1.5的時候被第一次引出,後來再android3.0和android3.1中得到了極大的發展,他們可以展示一些應用的常用信息
第8節 桌面小工具桌面小工具是可以放置在主界面的、快速控制應用的小助手。例如我們的音樂小工具,它可以幫助用戶在桌面上就完成音樂的暫停、播放、切換等操作,而不需要啟動應用本