AsyncTask
为解决不要在 UI 线程之外访问 Android UI 工具包Android 提供了几种途径来从其他线程访问 UI 线程。 以下列出了几种有用的方法:
Activity.runOnUiThread(Runnable)
[View.postDelayed(Runnable, long)](https://developer.android.com/reference/android/view/View.html?hl=zh-cn#postDelayed(java.lang.Runnable, long))
错误代码
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);// ❌:子线程更新UI
}
}).start();
}
正确代码(您可以通过使用View.post(Runnable)方法修复上述代码:)
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap bitmap =
loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() {// ✅:回到主线程,更新UI
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
优化代码,方便维护(上面代码,纵向很深,维护性很差)
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);// 子线程耗时操作
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);// 主线程更新UI
}
}
下面简要概述了 AsyncTask 的工作方法,但要全面了解如何使用此类,您应阅读
AsyncTask
参考文档:
可以使用泛型指定参数类型、进度值和任务最终值
方法 doInBackground()
会在工作线程上自动执行
onPreExecute() , onPostExecute() 和 onProgressUpdate() 均在 UI 线程中调用 doInBackground() 返回的值将发送到 onPostExecute() 您可以随时在 doInBackground() 中调用publishProgress()
,以在 UI 线程中执行 onProgressUpdate()
您可以随时取消任何线程中的任务
线程池
Timer与ScheduledExecutorService定时器的比较及其简单事例
Java线程池使用说明