众所周知:当UI线程阻塞超过20秒的时候都回引发ANR(Application Not Responding)异常。
对于这种异常有以下几种解决方案:
1.使用Handler实现线程之间的通信
2.Activity.runOnUiThread(Runnable)
3.View.post(Runnable)
4.View.postDelayed(Runnable,long)
后面三种很少使用,因为比较繁琐。
在Android中,我们可以使用异步消息处理机制(Handler,Message,MessaggeQueue,Looper)解决了在子线程中对UI进行操作。
但是这种方法使用起来特别麻烦,因此Android还提供了另外一些好用的工具,AsyncTask就是其中之一。
AsyncTask它也可以十分简单地从子线程切换到主线程。
由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须要创建一个子类去继承它。
直接用代码说明这个类及其里面的方法的使用情况:
package com.example.asynctaskdemo; import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; public class MainActivity extends Activity { private ProgressDialog progressDialog;//进度条对话框 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** * 这里设置progressDialog对象的一些属性 */ //启动这个任务 //new MyAsyncTask().execute(String... params); } /** * AsyncTask<Params, Progress, Result> * 参数讲解: * Params:在执行AsyncTask时需要传入的参数,可用于在后台任务中使用。 * Progress:后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。 * Result:当前任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。 */ class MyAsyncTask extends AsyncTask<String, Void, String>{ /** * 这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。 */ @Override protected void onPreExecute() { super.onPreExecute(); } /** * doInBackground(Params...) * 这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。 * 任务一旦完成就可以通过return语句来讲任务的执行结果返回,如果AsyncTask的第三个泛型 * 参数指定的时Void,就可以不返回任务执行结果。 * 注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度, * 可以调用publicProgress(Preogress...) */ @Override protected String doInBackground(String... params) { // TODO Auto-generated method stub return null; } /** * onProgressUpdate(Pregress...) * 当在后台任务中调用了publicProgress(Preogress...)方法后,这个方法就会很快被调用, * 方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作, * 利用参数中的数值就可以对界面元素进行相应地更新。 * */ @Override protected void onProgressUpdate(Void... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); } /** * onPostExecute(Result) * 当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。 * 返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如 * 提醒任务执行的结果,以及关闭掉进度条对话框等。 */ @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub super.onPostExecute(result); } } }
简单总结一下:使用AsyncTask,在doInBackground()方法中去执行具体的耗时任务,在onProgressUpdate()方法中进行UI操作,在onPostExecute()方法中执行一些任务
的收尾工作。启动这个任务(MyAsyncTask),使用这条语句:
new MyAsyncTask().execute(String... params);
使用AsyncTask时必须遵守如下规则:
1.必须在UI线程(主线程)中创建AsyncTask的实例
2.必须在UI线程中调用AsyncTask的execute()方法
3.每个AsyncTask只能被执行一次,多次调用都会引发异常。