AsyncTask的使用

AsyncTask作为一个比Handler好用的消息处理类,掌握它是必须的,废话少说,直接往下看!

-----------------------------------------------------------------------------------------------------------------

AsyncTask 是一个抽象类(public abstract class AsyncTask extends Object),如果想使用它的话,我们必须创建一个子类去继承它。

  看一下这个抽象类:android.os.AsyncTask<Params, Progress, Result>,指定了三个泛型参数,我们先分析一下这三个参数:

  1.  Params:在执行AsyncTask时需要传入的参数,可用于在后台任务中使用,这么说不懂?ok,下面代码会告诉你怎么用.

      new DownloadTask().execute(params) --> doInBackground(Integer... params)   // 这边的Integer可以自定义

  2. Progress:后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位

  3. Result:当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型,比如我们常使用Boolean或String类型作为返回类型。

  Notice:这三个参数是泛型参数,也就是说参数类型是根据要求传入的,所以在方法的使用过程中,一定要清晰参数类型的设定和使用。

  这里给出一个最简单的自定义AsyncTask的方式:

       class DownloadTask extends AsyncTask<Void, Integer, Boolean> {

        ......

      }

  当然,定义完一个继承AsyncTask的子类后,我们还需要覆写AsyncTask的几个方法:

    1.      onPreExecute()    

    2.     doInBackground(Params...)

    3.     onProgressUpdate(Progress...)

    4.     onPostExecute(Result)

下面,我们就这4个方法的使用流程作一个详细的介绍:

onPreExecute():这个方法顾名思义,就是在异步任务处理之前需要执行的操作,那么它操作什么?简单的说就是进行一些界面上的初始化操作,比如:显示一个进度条对话框等。这个方法不是我们的重点方法,但是在使用过程中巧妙使用可以增强界面的可观性。

protected void onPreExecute() {
  super.onPreExecute();      // 可以进行一些预处理
}

doInBackground(Params...):这个就是AsyncTask中最为重要的方法了,因为这个方法中的所有代码都会在子线程中运行,我们也是在这个方法中去处理所有的耗时任务。

直接看代码:

 
protected Boolean doInBackground(Integer... params) {      // 这边params是由execute()传进来的,这个execute方法可以在下面找到答案
  for (int i = 0; i < 101; i++) {
    publishProgress(i);                                 // 对主线程UI进行更新操作,将调用onProgressUpdate()方法
    try {       Thread.sleep(params[0]); // 休眠线程     } catch (Exception e) {       e.printStackTrace();     }   }   return true; // 任务完成后return一个结果,这边的Boolean类型的结果 }
 

通过以上的代码,我们可以发现:任务一旦完成就可以通过return语句来将任务的执行结果返回,如果AsyncTask的第三个泛型参数被指定的是Void,就可以不返回任务执行结果。

在这个方法中是不可以进行UI操作的(子线程是无法对主线程进行修改的),如果需要更新UI元素的话,就需要调用publishProgress(Progress...)方法来完成了。

onProgressUpdate(Progress...):当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就会很快被调用,此方法中的参数是从哪边传来的,我想不需要解释了吧。

在这个方法中,可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应地更新,为什么?上代码!。

protected void onProgressUpdate(Integer... values) {                                  // values[0] = i
  MainActivity.this.text.setText("当前进度是:" + String.valueOf(values[0]) + "%");   // 主线程进行操作
}

onPostExecute(Result):这个函数就是来执行return返回后的一些操作的,我们直接看下代码,就能理解。

 
protected void onPostExecute(Boolean b) {                                                         // b --> true
  if (b) {
     Toast.makeText(getBaseContext(), "Download succeed", Toast.LENGTH_SHORT).show();          // 后续操作
  } else {
    Toast.makeText(getBaseContext(), "Download failed", Toast.LENGTH_SHORT).show();
  }
}
 

那么,问题来了,我们定义好了类、同时覆写了各种方法,但是如何启动它?

如果想要启动这个任务,只需编写一行代码:new DownloadTask().execute();

protected void onCreate(Bundle savedInstanceState) {                  // 这个方法你不要说你不认识~
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  new DownloadTask().execute(100);                                  // 这样就可以启动异步类了
}

posted on 2016-04-22 10:54  Sun‘刺眼的博客  阅读(263)  评论(0编辑  收藏  举报

导航