AsyncTask 是在背景執行緒上運作的非同步技術,並將結果送回 UI Thread。
public class MinimalTask extends AsyncTask {
protected Object doInBackground(Object... object) {
// 實作要在背景執行緒上執行的任務
}
}
AsyncTask 工作流程
限制一次一個 AsyncTask
public class AsyncTaskStatusActivity extends Activity {
private AsyncTask myAsyncTask;
public void onExecute(View v) {
if(myAsyncTask!=null && myAsyncTask.getStatus() != AsyncTask.Status.RUNNING) {
myAsyncTask= new MyAsyncTask().execute();
}
}
private static class MyAsyncTask extends AsyncTask<String, Void, Void> {
protected void doInBackground(String... s) {
return null;
}
}
}
下載圖片 的範例
public class FileDownloadActivity extends Activity {
// 多個圖片的 urls
private static final String[] DOWNLOAD_URLS = {
"http://developer.android.com/design/media/devices_displays_density@2x.png",
"http://developer.android.com/design/media/iconography_launcher_example2.png"
};
DownloadTask mFileDownloaderTask;
// Views from layout file
private ProgressBar mProgressBar;
private LinearLayout mLayoutImages;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_download);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mProgressBar.setMax(DOWNLOAD_URLS.length);
mLayoutImages = (LinearLayout) findViewById(R.id.layout_images);
mFileDownloaderTask = new DownloadTask(this);
// 執行mFileDownloaderTask
mFileDownloaderTask.execute(DOWNLOAD_URLS);
}
@Override
protected void onDestroy() {
// 要同時取消 mFileDownloaderTask,避免 memory leak
super.onDestroy();
mFileDownloaderTask.setActivity(null);
mFileDownloaderTask.cancel(true);
}
private static class DownloadTask extends AsyncTask<String, Bitmap, Void> {
private FileDownloadActivity mActivity;
private int mCount = 0;
public DownloadTask(FileDownloadActivity activity) {
mActivity = activity;
}
public void setActivity(FileDownloadActivity activity) {
mActivity = activity;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// 執行過程中,更新畫面的 進度mActivity.mProgressBar.setVisibility(View.VISIBLE);
mActivity.mProgressBar.setProgress(0);
}
@Override
protected Void doInBackground(String... urls) {
for (String url : urls) {
if (!isCancelled()) {
Bitmap bitmap = downloadFile(url);
// 把圖片傳送到 UI Thread
publishProgress(bitmap);
}
}
return null;
}
@Override
protected void onProgressUpdate(Bitmap... bitmaps) {
super.onProgressUpdate(bitmaps);
if (mActivity != null) {
mActivity.mProgressBar.setProgress(++mCount);
ImageView iv = new ImageView(mActivity);
iv.setImageBitmap(bitmaps[0]);
mActivity.mLayoutImages.addView(iv);
}
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (mActivity != null) {
mActivity.mProgressBar.setVisibility(View.GONE);
}
}
@Override
protected void onCancelled() {
super.onCancelled();
if (mActivity != null) {
mActivity.mProgressBar.setVisibility(View.GONE);
}
}
private Bitmap downloadFile(String url) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory
.decodeStream((InputStream) new URL(url)
.getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
}
}
討論
- AsyncTask 具有全域的特性,使用越多,越有可能造成任務異常
- 需要使用 Looper 時,就要改用 HandlerThread
- 不需要回報進度的任務,可以改用 HandlerThread 或 Thread 實作
- 如果是長時間的任務,要改用 Service
沒有留言:
張貼留言