AsynTask解析

首先放流程图:

这里写图片描述

(侵删)


  1. 主线程调用AsynTask子类实例的execute()方法后,首先会调用onPreExecute()方法。onPreExecute()在主线程中运行,可以用来写一些开始提示代码。
  2. 之后启动新线程,调用doInBackground()方法,进行异步数据处理。
  3. 处理完毕之后异步线程结束,在主线程中调用onPostExecute()方法。onPostExecute()可以进行一些结束提示处理。

补充:在doInBackground()方法异步处理的时候,如果希望通知主线程一些数据(如:处理进度)。这时,可以调用publishProgress()方法。这时,主线程会调用AsynTask子类的onProgressUpdate()方法进行处理。

  1. 各个函数间数据的传递
    通过上面的调用关系,我们就可以大概看出一些数据传递关系。如下:
    execute()向doInBackground()传递。
    doInBackground()的返回值会传递给onPostExecute()。
    publishProgress()向progressUpdate()传递。
    要点:为了调用关系明确及安全,AsynTask类在继承时要传入3个泛型。第一个泛型对应execute()向doInBackground()的传递类型。第二个泛型对应doInBackground()的返回类型和传递给onPostExecute()的类型。第三个泛型对应publishProgress()向progressUpdate()传递的类型。传递的数据都是对应类型的数组,数组都是可变长的哦。可以根据具体情况使用。

注意:
1. 异步任务的实例必须在UI线程中创建。
2. execute(Params… params)方法必须在UI线程中调用。
3. 不要手动调用onPreExecute(),doInBackground(Params… params),onProgressUpdate(Progress… values),onPostExecute(Result result)这几个方法。
4. 不能在doInBackground(Params… params)中更改UI组件的信息。
5. 一个任务实例只能执行一次,如果执行第二次将会抛出异常。


代码展示:

 public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         button = (Button)findViewById(R.id.button03);
         progressBar = (ProgressBar)findViewById(R.id.progressBar02);
         textView = (TextView)findViewById(R.id.textView01);
         button.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
                 ProgressBarAsyncTask asyncTask = new ProgressBarAsyncTask(textView, progressBar);
                 asyncTask.execute(1000);
             }
         });
     }
//模拟网络环境
 public class NetOperator {

     public void operator(){
         try {
             //休眠1秒
             Thread.sleep(1000);
         } catch (InterruptedException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
     }

 }
/**
  * 生成该类的对象,并调用execute方法之后
  * 首先执行的是onProExecute方法
  * 其次执行doInBackgroup方法
  *
  */
 public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {

     private TextView textView;
     private ProgressBar progressBar;

     public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar) {
         super();
         this.textView = textView;
         this.progressBar = progressBar;
     }


     /**
      * 这里的Integer参数对应AsyncTask中的第一个参数
      * 这里的String返回值对应AsyncTask的第三个参数
      * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
      * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作
      */
     @Override
     protected String doInBackground(Integer... params) {
         NetOperator netOperator = new NetOperator();
         int i = 0;
         for (i = 10; i <= 100; i+=10) {
             netOperator.operator();
             publishProgress(i);
         }
         return i + params[0].intValue() + "";
     }


     /**   
      * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)
      * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置
      */
     @Override
     protected void onPostExecute(String result) {
         textView.setText("异步操作执行结束" + result);
     }



     //该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置
     @Override
     protected void onPreExecute() {
         textView.setText("开始执行异步线程");
     }


     /**
      * 这里的Intege参数对应AsyncTask中的第二个参数
      * 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行
      * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作
      */
     @Override
     protected void onProgressUpdate(Integer... values) {
         int vlaue = values[0];
         progressBar.setProgress(vlaue);
     }
 }

猜你喜欢

转载自blog.csdn.net/adonis044/article/details/80040169