• Android备注26.Android异步任务(AsyncTask)


    转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)
    一、引言
        我们知道Android的UI线程主要负责处理用户的按键事件用户触屏事件屏幕画图事件等,对于其它的操作尽量不要在UI线程中实现,由于这些操作非常有可能会堵塞UI线程,比方一些耗时操作,会导致UI界面停止响应,从而减少了用户的体验。所以,为了避免UI线程失去响应的问题,Android建议将耗时操作放在新线程中完毕。但新线程也可能须要动态更新UI组件:比方须要从网上获取一个网页,然后在TextView中将其源码显示出来,此时就应该将连接网络,获取网络数据的操作(耗时)放在新线程中完毕。
        可是。问题来了:当获取网络数据之后。因为新线程不同意直接更新UI组件,我们该怎样更新UI组件数据呢?为了解决新线程不能更新UI组件问题。Android提供了例如以下几种解决方式:
    (1)使用Handler消息传递机制实现线程之间的通信(如上一篇文章所述);
    (2)Activity.runOnUiThread(Runnable);
    (3)View.post(Runnable);
    (4)View.postDelayed(Runnable long);
    (5)异步任务。又因为(2)~(4)方式有可能导致编程有点繁琐。而异步任务则可简化这样的操作。
    二、AsyncTask简单介绍
        Android的类AsyncTask对线程间通讯进行了包装,提供了简易的编程方式使后台线程和UI线程进行通讯:后台线程运行异步任务。并把操作结果通知UI。不再须要子线程和Handler就能够完毕异步操作而且刷新用户界面
    1.AsyncTask类
        AsyncTask<>是一个抽象类。通经常使用于被继承,继承AsyncTask时须要指定例如以下三种泛型參数:
    (1)Params:启动任务运行输入參数的类型;
    (2)Progress:后台任务完毕的进度值(百分比)的类型;
    (3)Result:后台运行任务完毕后返回结果的类型,如String、Integer;
    2.Async类中主要方法
    (1)onPreExecute():该方法将在运行实际的后台操作前UI线程调用

    能够在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这种方法能够不用实现。

    -----(UI线程调用,后台线程未启动,初始化工作)
    (2)doInBackground(Params...values):将在onPreExecute 方法运行后立即运行,该方法运行在后台线程中。这里将主要负责运行那些比較耗时的后台处理工作。能够调用 publishProgress()方法来实时更新任务进度。该方法是抽象方法,子类必须实现。
    -----(后台线程调用。运行后台任务)
    (3)onProgressUpdate(Progress...values):在publishProgress方法被调用后,UI 线程将调用这种方法从而在界面上展示任务的进展情况,比如通过一个进度条进行展示。
    -----(UI线程调用。展现后台任务进展)
    (4)onPostExecute(Result):在doInBackground 运行完毕后。onPostExecute 方法将被UI线程调用,后台的计算结果(doInBackground方法返回值)将通过该方法传递到UI线程,而且在界面上展示给用户。

    -----(UI线程调用。显示后台线程执行结果)
    (5) onCancelled():在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。
    -----(UI线程调用,取消后台线程) 
    三、异步任务处理开发步骤
    1.创建AsyncTask的子类,并为三个泛型參数指定类型。假设某个泛型參数不须要指定类型,则将它指定为Void。
    2.依据须要实现AsyncTask上述五中方法;
    3.调用AsyncTask子类的实例的execute(Params... params)開始运行耗时任务。

    另外,使用AsyncTask类须要遵守的下面准则
    (1)Task的实例必须在UI线程中创建;
    (2)execute(Params...)方法必须在UI线程中调用;
    (3)不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...)这几个方法。须要在UI线程中实例化这个task来调用;
    (4)该task仅仅能被运行一次。否者多次调用时将会出现异常
    四、源代码实战
    1.实现功能
    2.源代码实现
    (1)MainActivity.java
    功能:用以获取界面组件。实例化一个AsyncTask子类对象并调用其exeute(Integer....params)方法以指定參数params执行一个任务。
    package com.example.android_asynctask;
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    public class MainActivity extends Activity {
     private Button downbtn;
     private TextView textView;
     private ProgressBar progressBar;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            downbtn = (Button)findViewById(R.id.download);
            textView = (TextView)findViewById(R.id.text);
            progressBar = (ProgressBar)findViewById(R.id.progressBar);
            final DownloadTest download = new DownloadTest(textView,progressBar);	//获取一个DownloadTest对象。并传递组件对象參数
            downbtn.setOnClickListener(new OnClickListener()
            {
       @Override
       public void onClick(View v) {
        download.execute(200);
       }
            });
           
        }
    }
    (2)DownloadTest.java
    功能:继承于AsyncTask的子类。当中onPreExecute()作用是为执行后台线程(子线程)完毕初始化工作;doInBackground方法执行后台线程;onProgressUpdate方法更新UI;onPostExecute方法处理后台线程执行结果。
    package com.example.android_asynctask;
    import android.graphics.Color;
    import android.os.AsyncTask;
    import android.view.View;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    public class DownloadTest extends AsyncTask<Integer,Integer,String>
    {
     private TextView tv;
     private ProgressBar pb;
     //带參数构造方法
     DownloadTest(TextView text,ProgressBar bar)
     {
      this.tv = text;
      this.pb = bar;
     }
     //不带參数构造方法
     DownloadTest()
     {
     }
     /*1.onPreExecute方法
      * 为子线程(后台)执行初始化相关内容
      */
     protected void onPreExecute() {
          tv.setVisibility(View.VISIBLE);	 //设置显示文本组件
          pb.setVisibility(View.VISIBLE);	 //设置显示运行进度条
          super.onPreExecute();
     }
     /*2.doInBackground方法
      *  执行一个后台线程,该线程实现每arg0[0]毫秒调用一次onProgressUpdate方法
      */
     protected String doInBackground(Integer... arg0) {
      for(int i=0;i<100;i++)
      {
       publishProgress(i);	 //调用onProgressUpdate方法并传递參数i
       try {
        Thread.sleep(arg0[0]);	//累加一次,线程休眠argo[0]毫秒
       } catch (InterruptedException e) {
        e.printStackTrace();
       }
      }
      return "完成下载";	 //后台子线程执行完成后。返回的值
     }
     /*3.onProgressUpdate方法
      * 调用publishProgress(i)时调用该方法,并传递參数i给形參values[0]*/
    
     @Override
     protected void onProgressUpdate(Integer... values) {
      pb.setProgress(values[0]);	 //设置进度条值
      tv.setText("已经下载"+values[0]+"%");	 //文本组件显示提示信息
      super.onProgressUpdate(values);
     }
     /*4.onPostExecute
      * 处理后台线程得到的结果
      * */
     protected void onPostExecute(String result) {
      pb.setVisibility(View.INVISIBLE);	//隐藏进度条
      tv.setVisibility(View.VISIBLE);	//显示UI文本显示框组件
      tv.setText(result);
      tv.setTextSize(20);
      tv.setTextColor(Color.RED);
      super.onPostExecute(result);
     }
    }


    效果演示:


    源代码分析:
        通过源代码我们能够知道。主线程通过调用AsyncTask子类的execute()方法,进而调用AsyncTask子类的onPreExecute方法,用以再执行后台线程之前为其初始化相关内容。

    然后,在新创建的子线程中调用doInBackground()方法实现后台线程功能并通过publishProgress()方法调用onProgressUpdate()方法更新UI内容,最后在主线中执行onPostExecute方法来处理后台线程执行的结果。

    注意:当中仅仅有doInBackground()方法,以及publishProgress()方法是在子线程中运行的。其它的方法都是在主线程中运行的。所以能够在这些方法中更新界面组件。

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    iOS加载HTML, CSS代码
    iOS搜索指定字符在字符串中的位置
    【解决方法】You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE)
    刷新指定行或区 cell
    支付宝获取私钥和公钥
    什么是Git?
    第三方库AFNetworking 3.1.0的简单使用
    转:KVC与KVO机制
    转:常用的iOS开源库和第三方组件
    转:setValue和setObject的区别
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4678403.html
Copyright © 2020-2023  润新知