詳解Android 中AsyncTask 的使用
詳解Android 中AsyncTask 的使用
1、首先我們來看看AsyncTask 的介紹:
Handler 和 AsyncTask 都是android 中用來實(shí)現(xiàn)異步任務(wù)處理的方式;其中:
Handler 實(shí)例向 UI 線程發(fā)送消息,完成界面更新,
優(yōu)點(diǎn):對整個(gè)過程控制的比較精細(xì);
缺點(diǎn):代碼相對臃腫,多個(gè)任務(wù)同時(shí)執(zhí)行時(shí),不易對線程進(jìn)行精確的控制;
AsyncTask :比Handler 更輕量級一些,適用于簡單的異步處理;
優(yōu)點(diǎn):簡單 | 快捷 | 過程可控;
缺點(diǎn):使用多個(gè)異步操作時(shí)就變得復(fù)雜起來;
2、AsyncTask 的定義:(AsyncTask 定義了三種泛型類型)
public abstract class AsyncTask<Params,Progress,Result>{...}
說明:
Params :啟動任務(wù)執(zhí)行的輸入?yún)?shù),例如:HTTP 請求的URL;
Progress: 后臺任務(wù)執(zhí)行的百分比;
Result:后臺執(zhí)行任務(wù)最終返回的結(jié)果,比如String;
3、AsyncTask 異步任務(wù)的執(zhí)行步驟:(以下方法除execute(Params... params),在AsyncTask中重寫),下列是相關(guān)方法的介紹:
A、execute(Params... params) :
執(zhí)行一個(gè)異步任務(wù),需要我們在UI線程中調(diào)用,觸發(fā)任務(wù)
B、OnPreExecute():
execute(Params... params)調(diào)用后立即執(zhí)行,一般用于在執(zhí)行后臺任務(wù)前對UI做一些標(biāo)記; 例如,可以在此處顯示進(jìn)度對話框;
C、doInBackground(Params.. params):
onPreExecute() 完成后執(zhí)行,后臺執(zhí)行,處理比較耗時(shí)的操作;此處不能操作UI,執(zhí)行的過程中調(diào)用publishProgress(Progress... values)來更新進(jìn)度信息;
D、onProgressUpdate(Progress... values):
在調(diào)用publicshProgress(Progress... values)方法執(zhí)行,直接將進(jìn)度信息更新到UI組建上;此方法在主線程上執(zhí)行,用于顯示任務(wù)執(zhí)行的進(jìn)度;
E、onPostExecute(Result result):
此方法在主線程中執(zhí)行,當(dāng)后臺的操作結(jié)束時(shí),此方法會被調(diào)用,計(jì)算結(jié)果作為參數(shù)傳遞到此方法中,直接將結(jié)果顯示到UI組建上。
F、cancel(); :
取消一個(gè)正在執(zhí)行的任務(wù),在UI線程中完成,用AsyncTask的對象進(jìn)行調(diào)用,參數(shù)為true/false;
4、使用AsyncTask 時(shí)注意事項(xiàng):
A、異步任務(wù)實(shí)例必須在UI線程中創(chuàng)建;
B、execute(Params... params) 方法必須在UI線程中調(diào)用;
C、不要手動的調(diào)onPreExecute().doInBackground().onProgressUpdate().onPostExecute()這幾個(gè)方法;
D、不能在doInBackground(Params... params) 中更改組件信息;
E、一個(gè)任務(wù)實(shí)例只能執(zhí)行一次,如果執(zhí)行第二次會拋出異常;
5、案例:使用AsyncTask 實(shí)現(xiàn)圖片的下載:
Activity類,主程序的入口:
public class MainActivity extends Activity {
// 程序入口
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyAsyncTask my = new MyAsyncTask();
my.execute("http://photocdn.sohu.com/20110927/Img320705637.jpg");
}
}
AsyncTask 派生類,實(shí)現(xiàn)異步任務(wù):
package com.sun.asynctask;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.http.HttpConnection;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
/**
* 異步任務(wù),實(shí)現(xiàn)網(wǎng)頁內(nèi)容的獲取
*
*
* 生成該類的對象,并調(diào)用execute方法之后
*
* 首先執(zhí)行的是onProExecute() 方法,
*
* 其次執(zhí)行的doInBackground()方法
*/
public class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> {
/**
* 在execute() 方法執(zhí)行后立即執(zhí)行,運(yùn)行在UI線程中,
* 在后臺任務(wù)開始前執(zhí)行,用于標(biāo)識UI界面
*/
protected void onPreExecute() {
super.onPreExecute();
Log.i("msg","onPreExecute()...");
}
/**
* 后臺執(zhí)行耗時(shí)的任務(wù);
*
* 方法中的 String 參數(shù)對應(yīng) AsyncTask的第一個(gè)參數(shù);
* 返回的 Bitmap 對應(yīng)的是AsyncTask 的第三個(gè)參數(shù);
*
* 該方法并不運(yùn)行在UI線程中,主要用于異步操作,可以調(diào)用publishProgress()方法觸發(fā)
* onProgressUpdate對UI進(jìn)行操作;
*
*/
protected Bitmap doInBackground(String... params) {
Log.i("msg","doInBackground(String... params)...");
try {
/* 網(wǎng)絡(luò)訪問方式 二 */
/*
URL url = new URL(params[0]);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.connect(); // 開始連接
int zong = connection.getContentLength();
InputStream is2 = connection.getInputStream();
*/
/* 開始網(wǎng)絡(luò)訪問數(shù)據(jù) */
HttpGet hg = new HttpGet(params[0]); // 此處注意參數(shù)的用法
HttpClient hc = new DefaultHttpClient();
HttpResponse hr = hc.execute(hg); // 發(fā)送請求,得到響應(yīng)
// 判斷請求是否成功
if(hr.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
Log.i("msg", "access success...");
HttpEntity he = hr.getEntity();
InputStream is = he.getContent(); // 獲取輸入流對象,好比搭橋
long total = he.getContentLength(); // 文件的總字節(jié)數(shù)
ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 輸出流,臨時(shí)容器,用于裝從is中流出的數(shù)據(jù)
byte[] buffer = new byte[1024]; // 緩存容器,每次裝載1024 個(gè)字節(jié)數(shù)據(jù)
int len = 0; // 每次讀的字節(jié)數(shù)
int curLen = 0 ; // 已讀多少數(shù)據(jù)
while((len=is.read(buffer))!=-1){ // 當(dāng)len !=-1 時(shí),也就是還有數(shù)據(jù)可讀
Log.i("msg","begin read data..."+len+",total:"+total);
baos.write(buffer, 0, len); // 向臨時(shí)容器中裝數(shù)據(jù)
curLen=curLen+len; // 更新已讀的數(shù)據(jù)
/* 在UI顯示當(dāng)前讀取的進(jìn)度 , 調(diào)用次方法觸發(fā)onProgressUpdate() 方法執(zhí)行 */
publishProgress((int)(((float)curLen/total)*100));
}
Bitmap bitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, (int)total);
is.close();
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 括號中的參數(shù):String 對應(yīng)的是AsyncTask 的第三個(gè)參數(shù),也就是
* 接收了 從doInBackground() 返回的結(jié)果;
* 此方法在 doInBackground() 方法執(zhí)行結(jié)束后執(zhí)行,運(yùn)行在UI線程中,
* 可以對UI進(jìn)行更新
*/
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
Log.i("msg","onPostExecute(String result)..."+result.getHeight());
}
/**
* 方法括號中的Integer 對應(yīng)AsyncTask 中的第二個(gè)參數(shù);
* 在doInBackground() 中每次調(diào)用publishProgress() 時(shí)被執(zhí)行;
* 該方法是在UI線程中的,所以可以用于對UI進(jìn)行更新
*/
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.i("msg","onProgressUpdate(Integer... values)..."+values[0]);
}
/**
* 圖片的下載
*/
public HttpURLConnection downPic(String urltemp){
try {
URL url = new URL(urltemp); // 確定連接地址
// 打開一個(gè)連接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect(); // 開始連接
return connection;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
以上就是Android AsyncTask的應(yīng)用實(shí)例,如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- Android 使用AsyncTask實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳
- Android 使用AsyncTask實(shí)現(xiàn)斷點(diǎn)續(xù)傳
- Android 使用AsyncTask實(shí)現(xiàn)多任務(wù)多線程斷點(diǎn)續(xù)傳下載
- Android多線程AsyncTask詳解
- Android中使用AsyncTask實(shí)現(xiàn)下載文件動態(tài)更新進(jìn)度條功能
- Android AsyncTask詳解及使用方法
- Android AsyncTask實(shí)現(xiàn)異步處理任務(wù)的方法詳解
- Android帶進(jìn)度條的下載圖片示例(AsyncTask異步任務(wù))
- 淺談Android中AsyncTask的工作原理
相關(guān)文章
Android 程序執(zhí)行Linux命令的解決方法及注意事項(xiàng)
這篇文章主要介紹了Android 程序執(zhí)行LINUX命令的解決方法及注意事項(xiàng),本文通過問題描述最終到解決方法,給大家介紹的非常詳細(xì),需要的朋友可以參考下2017-12-12
Android倒計(jì)時(shí)神器(CountDownTimer)
這篇文章主要為大家詳細(xì)介紹了Android倒計(jì)時(shí)神器CountDownTimer,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-01-01
Android使用 Retrofit 2.X 上傳多文件和多表單示例
本篇文章主要介紹了Android使用 Retrofit 2.X 上傳多文件和多表單示例,具有一定的參考價(jià)值,有興趣的小伙伴一起來了解一下2017-08-08
Android RecycleView滑動停止后自動吸附效果的實(shí)現(xiàn)代碼(滑動定位)
這篇文章主要介紹了Android RecycleView滑動停止后自動吸附效果的實(shí)現(xiàn)代碼(滑動定位),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
分享Android開發(fā)自學(xué)筆記之AndroidStudio常用功能
這篇文章主要給大家分享Android開發(fā)自學(xué)筆記之AndroidStudio常用功能的相關(guān)資料,需要的朋友可以參考下2015-12-12
Android實(shí)現(xiàn)簡單旋轉(zhuǎn)動畫
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡單旋轉(zhuǎn)動畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07

