編輯:關於Android編程
官方文檔中隊AsyncTask的解釋是:AsyncTask更加適用於UI線程。這個類允許執行後台操作並在UI界面上發布結果,而不必處理多線程。AsyncTask是圍繞Thread和Handler設計的一個輔助類,它不構成一個通用的線程框架。Asynctasks應該用於短作業(最多幾秒鐘)。
說的簡單一點,AsyncTask其實就是Android提供的一個輕量級異步類。使用的時候可以自己自定義一個類去繼承AsyncTask,就能在自定義類中實現異步操作,並且該類的實現方法中提供了接口來反饋當前異步任務執行的程度,最後還可以將執行的結果傳遞給UI線程。
自定義類繼承AsyncTask代碼如下:
private class DownloadFilesTask extends AsyncTask {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
開啟異步任務代碼如下:
new DownloadFilesTask().execute(url1, url2, url3);
1. 三個泛型類型
Params:參數。啟動任務執行需要輸入的參數,比如HTTP請求的URL Progress:過程。後台任務執行的百分比
Result:結果。後台執行任務最終返回的結果,比如String
這三個參數對四個步驟的方法的參數類型和返回值分別進行約束,如果沒有約束的話,參數類型都為Void
private class MyTask extends AsyncTask { ... }
2. 四個步驟
onPreExecute()
調用時機:第一個執行,並且在異步任務開始之前調用 執行線程:主線程 方法參數:無 方法返回值:無
方法的作用:用於提醒用戶,當前正在請求數據,一般用來彈出進度對話框
@Override
protected void onPreExecute() {
super.onPreExecute();
// 運行在前台,初始化UI操作
mDialog = new ProgressDialog(context);
mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mDialog.show();
}
doInBackground()
調用時機:在onPreExecute方法執行完畢之後,這個方法一定會執行 執行線程:子線程
方法參數
由類上面的第一個泛型Params來限定 從execute方法裡面傳遞進來
方法返回值
由類上面的第三個泛型Result來限定 將被當做onPostExecute()方法的參數
方法的作用:在後台線程當中執行耗時操作,比如聯網請求數據。在執行過程中可以調用publicProgress()來更新任務的進度
@Override
protected Boolean doInBackground(Void... params) {
List list = SmsUtil.getAllSms(context);
try {
// 序列化器
XmlSerializer xs = Xml.newSerializer();
File file = new File(context.getFilesDir(), "sms.xml");
// 設置輸出路徑
xs.setOutput(new FileOutputStream(file), "utf-8");
xs.startDocument("utf-8", true);
xs.startTag(null, "smss");
for (int i = 0; i < list.size(); i++) {
SmsBean bean = list.get(i);
xs.startTag(null, "sms");
xs.startTag(null, "address");
xs.text(bean.address);
xs.endTag(null, "address");
xs.startTag(null, "date");
xs.text(bean.date + "");
xs.endTag(null, "date");
xs.startTag(null, "type");
xs.text(bean.type + "");
xs.endTag(null, "type");
xs.startTag(null, "body");
xs.text(bean.body);
xs.endTag(null, "body");
xs.endTag(null, "sms");
SystemClock.sleep(100);
publishProgress(i + 1, list.size());
}
xs.endTag(null, "smss");
xs.endDocument();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
onProgressUpdate()
調用時機:在publishProgress()方法執行之後調用 執行線程:主線程
方法參數
由類上面的第二個泛型來限定。 參數是從publishProgress 傳遞進來 方法返回值:無
方法的作用:更新進度條
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// 更新UI
mDialog.setMax(values[1]);
mDialog.setProgress(values[0]);
}
onPostExecute()
調用時機:在doInBackground 執行完畢之後調用 執行線程:主線程
方法參數
由類上面的第三個泛型來限定。 doInBackground的返回值就是這個方法的參數
方法返回值:無
方法的作用:相當於Handler的handleMessage()方法,在這裡面可以對doInBackground()方法得到的結果進行處理,更新UI
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
listener.onSuccess();
} else {
listener.onFailure();
}
mDialog.dismiss();
}
3. 需要遵守的准則
任務必須在主線程中執行 任務對象必須在主線程中構建 execute方法必須在主線程中執行 四個步驟中的方法不能直接調用,publicProgress()方法可以在類中暴露一個方法出去,讓外邊調用
任務只能執行一次
1.6開始的時候,可以並發執行多個任務,但是3.0之後,只能允許單個任務執行。如果真的想要多任務並發執行,那麼可以運行在自己的線程池裡面
mTask.executeOnExecutor(exec, params)
五、接口回調簡單使用
使用接口回調,一般有以下四個步驟,通過這四個步驟就能形成一個簡單的回調。在Android中很多地方都用到了接口回調,比如控件的點擊事件,GitHub上的許多開源框架也都用了接口回調,開發過程了也頻頻涉及到接口回調,所以這是一個很重要的知識點。
定義接口,可以是內部接口,也可以是自定義接口
/**
* 定義回調接口
*/
public interface OnTaskListener{
/**
* 成功之後調用這個方法
*/
void onSuccess();
/**
* 失敗之後調用這個方法
*/
void onFailed();
}
接收接口實現類對象
public BackupTask(Context context, OnTaskListener listener) {
mContext = context;
mListener = listener;
}
通過接口實現類對象,訪問對應的方法
if(result){
mListener.onSuccess();
// == ToastUtil.showShort(mContext,"備份成功");
}else{
mListener.onFailed();
// == ToastUtil.showShort(mContext,"備份失敗");
}
在實現中編寫調用方法執行操作的代碼
// 直接調用工具類的回調方法來彈出吐司
new SmsUtil().backUpSms(this, new SmsUtil.OnTaskListener() {
@Override
public void onSuccess() {
ToastUtil.showShort(MainActivity.this,"備份成功");
}
@Override
public void onFailure() {
ToastUtil.showShort(MainActivity.this,"備份失敗");
}
});
使用GraphicalView畫柱狀圖和餅圖 一.achartengine庫的下載,下載地址: www.2cto.com 下載完成後,把jar文件粘貼到li
1 HSDPA 簡介HSDPA中引入的HS-DSCH棄用了R99中的功率控制技術、軟切換技術和可變擴頻增益技術。同時引入了一系列關鍵技術:1) 更短的無線幀結構;(2ms
在做商城的項目中,有這麼個需求,就是一個產品下有兩個價格,一個是市場價,一個是銷售價,這時要把市場價添加個刪除線;剛開始遇到這個時,在網上找了半天的資料,看到最多的就是用
ChangeMode項目地址:ChangeMode Implementation of night mode for Android. 用最簡單的方式實現夜間模式,支持L