安卓的中只有主线程UI线程才能对UI界面进行更新,这让就使UI具有了稳定性和准确性避免了多线程对UI的操作造成的混乱,但是同时处理下载任务,文件操作等耗时操作放在主线线程就会造成线程阻塞,系统会检测这样的阻塞,如果时间过长会报ANR错误,所以要把耗时的操作放在子线程利,所以安卓提供了封装好的AsyncTask作用于子线程更新UI,和简化异步操作
官网解析
AsyncTask must be subclassed to be used. The subclass willoverride at least one method (doInBackground(Params...)), and most often will override a second one (onPostExecute(Result).)
Here is an example of subclassing:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
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");
}
}
The three types used by an asynchronous task are thefollowing:
1. Params,the type of the parameters sent to the task upon execution.
2. Progress, thetype of the progress units published during the background computation.
3. Result,the type of the result of the background computation.
AsyncTask函数和参数------------------------------------------------------------------
AsyncTask被继承使用,需要指定三个泛型参数Params,Progress和Result
doInBackground(Params...)函数必须要重写,执行后台完成任务,不能再这里更新UI
onPreExecute(),执行耗时操作前调用,常常用于初始==
onProgressUpdate(Progress...),在doInBackground中调用publishProgress方法,UI 线程将调用这个方法从而在界面上展示任务的进展情况
onPostExecute(Result), 在doInBackground执行完成自动调用,返回值会传递给该方法
调用顺序: onPreExecute()->doInBackground(Params...)-> onProgressUpdate(Progress...)-> onPostExecute(Result)
public class ImageAcivity extends Activity {
private ImageView imageView;
private ProgressBar progressBar;
private String url = "http://c.hiphotos.baidu.com/zhidao/pic/item/8c1001e93901213f72abcb8857e736d12e2e95ce.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(R.layout.imageloder);
imageView = (ImageView) this.findViewById(R.id.imageView);
progressBar = (ProgressBar) this.findViewById(R.id.progressBar);
new MyImageAsyncTask().execute(url);
}
class MyImageAsyncTask extends AsyncTask<String,Void, Bitmap>{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
System.out.println("onPreExecute");
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
System.out.println("onPostExecute");
imageView.setImageBitmap(result);
progressBar.setVisibility(View.GONE);
}
@Override
protected Bitmap doInBackground(String... params) {
String url = params[0];
Bitmap bitmap = null;
try {
System.out.println("doInBackground");
URLConnection connection = new URL(url).openConnection();
InputStream in = connection.getInputStream();
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
System.out.println("onProgressUpdate");
}
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5px"
tools:context="com.example.asynctaskexample.MainActivity" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/imageView"
/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:layout_centerInParent="true"
android:visibility="gone"
/>
</RelativeLayout>
主线程中调用执行,不能执行excute方法两次会报运行时异常,不能在异步处理函数doInBackGround中更新UI,其他两个函数中提供了UI更新