基本用法
繼承時為AsyncTask類指定三個泛型參數(shù),
- Params
在執(zhí)行AsyncTask時需要傳入的參數(shù),可用于在后臺任務中使用。 - Progress
后臺任務執(zhí)行時,如果需要在界面上顯示當前的進度,則使用這里指定的泛型作為進度單位。 - Result
當任務執(zhí)行完畢后,如果需要對結果進行返回,則使用這里指定的泛型作為返回值類型。
實現(xiàn)一個顯示圖片的功能
public class ShowPicTask extends AsyncTask<String, Integer, Bitmap> {
private ImageView mImageView;
private ProgressBar mProgressBar;
public ShowPicTask(ImageView imageView, ProgressBar progressBar) {
mImageView = imageView;
mProgressBar = progressBar;
}
// 在后臺任務開始執(zhí)行之前調(diào)用,用于進行一些界面上的初始化操作,如顯示一個進度條對話框
@Override
protected void onPreExecute() {
mProgressBar.setProgress(0);
}
// 子線程中運行,任務完成會return執(zhí)行結果
@Override
protected Bitmap doInBackground(String... strings) {
Bitmap bitmap = null;
try {
URL imageUrl = new URL(strings[0]);
HttpURLConnection conn = (HttpURLConnection) imageUrl
.openConnection();
conn.setConnectTimeout(10000);
conn.setRequestMethod("GET");
if (conn.getResponseCode() == 200) {
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
// 進行UI操作
@Override
protected void onProgressUpdate(Integer... values) {
mProgressBar.setProgress(values[0]);
}
// 任務執(zhí)行完會retrun結果,就好執(zhí)行此方法,返回結果做為參數(shù)傳到此方法中
@Override
protected void onPostExecute(Bitmap result) {
mProgressBar.setVisibility(View.GONE);
mImageView.setImageBitmap(result);
}
}
執(zhí)行異步任務
new ShowPicTask(imageView, progressBar).execute("https://www.baidu.com/img/bdlogo.png");
基本原理
//早期版最多同時執(zhí)行5個線程,多余的需要等待,同時執(zhí)行超過128個線程時會崩潰
// CPU 數(shù)量決定
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE = 1;
……
// 采用線程池執(zhí)行
private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);

execute.png
excute() 方法調(diào)用 excuteOnExecuteor

excuteOnExecuteor.png
先調(diào)用onPreExecute,然后再使用線程池執(zhí)行異步任務

handler.png
采用Handler 進行通知,創(chuàng)建的Handler使用的是主線程的Looper,