zoukankan      html  css  js  c++  java
  • 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);                                  // 这样就可以启动异步类了
    }
  • 相关阅读:
    PCB Genesis加邮票孔(线与线)实现算法
    PCB 无需解压,直接读取Zip压缩包指定文件 实现方法
    PCB MS SQL CLR聚合函数(函数作用,调用顺序,调用次数) CLR说明
    PCB MS SQL表值函数与CLR 表值函数 (例:字符串分割转表)
    PCB MS CLR 聚合函数 joinString加排序实现
    PCB 奥宝LDI 输出自动改周期检测内容
    如何介绍项目
    二叉树的深度
    51单片机汇编指令手册
    SSM父子工程搭建
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5420418.html
Copyright © 2011-2022 走看看