zoukankan      html  css  js  c++  java
  • Android开发之异步具体解释(二)之AsyncTask

      请尊重他人的劳动成果,转载请注明出处:Android开发之异步具体解释(二)之AsyncTask 

    http://blog.csdn.net/fengyuzhengfan/article/details/40212745

            我曾在《Android开发之异步具体解释(一)之Thread+Handler》一文中介绍过通过Thread+Handler实现异步操作。感兴趣的朋友能够看一下。

            尽管Thread+Handler能够实现更新主线程的UI并实现异步,但Thread+Handler模式须要为每个任务创建一个新的线程,任务完毕后通过Handler实例向UI线程发送消息,完毕界面的更新,这样的方式对于整个过程的控制比較精细,但也是有缺点的,比如代码繁琐,在多个任务同一时候运行时,不易对线程进行精确的控制。

    以下就介绍一下AndroidAsyncTask的使用:

     

    AsyncTask简单介绍:


            从Android 1.5開始系统将AsyncTask引入到android.os包中。AsyncTask,是android提供的轻量级的异步类,能够直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步运行的程度(能够通过接口实现UI进度更新),最后反馈运行的结果给UI主线程。


    类概述:


            AsyncTask的出现使得使用UI线程变得轻巧而简单。这个类同意运行后台操作,并将操作结果更新到UI线程上而无需操作threads和handlers。

            AsyncTask的设计是环绕线程和Handler一个辅助类,并不构成一个通用线程框架。异步任务最好应採用短作业。假设你须要保持执行非常长一段时间的线程,能够使用java.util.concurrent包等提供的ThreadPoolExecutor和FutureTask等各种API来替代。

            异步任务被定义执行在后台线程和要公布结果在UI线程上的一个运算。 异步任务被定义为ParamsProgressResult 3通用 类型,和onPreExecute,doInBackground,onProgressUpdateonPostExecute  4个步骤。

     

    AsyncTask的定义


    AsyncTask的定义了三种泛型类型 ParamsProgressResult

    public  abstract  class  AsyncTask<Params, Progress, Result>

    Params 启动任务运行的输入參数,比方HTTP请求的URL。

    Progress 后台任务运行的进度。

    Result 后台运行任务终于返回的结果,比方String。


    AsyncTask中主要方法介绍:


    onPreExecute() ,该方法将在运行实际的后台操作前被UI 线程调用。能够在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这种方法能够不用实现。

    doInBackground(Params...) ,将在onPreExecute 方法运行后立即运行,该方法运行在后台线程中。这里将主要负责运行那些非常耗时的后台处理工作。能够调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。

    onProgressUpdate(Progress...) publishProgress(Progress...)方法被调用后,UI 线程将调用这种方法从而在界面上展示任务的进展情况,比如通过一个进度条进行展示。

    onPostExecute(Result)在doInBackground 运行完毕后,onPostExecute方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,而且在界面上展示给用户。

    onCancelled(),在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。


    使用AsyncTask的步骤


            AsyncTask同意你在你的用户界面上运行异步操作。它在一个子线程中运行耗时的操作,然后在UI线程上公布运行结果,而不须要你来处理Thread和Handler。

            要使用AsyncTask,你必须继承AsyncTask和实现doInBackground()回调方法,AsyncTask执行在后台的一个线程池中。若要更新你的UI,你应该实现onPostExecute()方法,它从doInBackground()方法中获取的结果,并执行在UI线程中,这样你就能够安全地更新你的UI你能够在UI线程中调用execute()方法開始你任务。


    使用AsyncTask的步骤:

    1)创建一个继承AsyncTask的类

    2) 实现AsyncTask中定义的抽象方法doInBackground(Params...),然后依据须要重写它的其他方法。

    3) 调用execute()来開始任务。

    看一个样例:

    // <String,Integer, Bitmap>
    // 表示从调用位置传来的參数
    // Integer:表示读取网络数据的进度
    // 从网络返回的值
    class NetTask extends AsyncTask<String, Integer, Bitmap> {
        private String path;
        private ImageView iv;
     
        public NetTask(String path, ImageView iv) {
           this.path = path;
           this.iv = iv;
        }
     
        // 主线程中,反馈网络訪问进度
        @Override
        protected void onProgressUpdate(Integer... values) {
           super.onProgressUpdate(values);
           Log.i("NetUtil", "values=" + values[0]);
        }
     
        // 主线程中,子线程运行之前运行
        @Override
        protected void onPreExecute() {
           super.onPreExecute();
        }
     
        // 子线程
        @Override
        protected Bitmap doInBackground(String... params) {
           try {
               URL url = new URL(path);
               HttpURLConnection conn = (HttpURLConnection) url
                      .openConnection();
               // 设置一些连接属性
               conn.setConnectTimeout(5000);
               conn.setRequestMethod("GET");// POST
               // 设置http头信息
               //conn.setRequestProperty("Content-type", newValue)
               if (conn.getResponseCode() == 200) {
                  InputStream is = conn.getInputStream();
                  return BitmapFactory.decodeStream(is);
               }
           } catch (MalformedURLException e) {
               e.printStackTrace();
           } catch (IOException e) {
               e.printStackTrace();
           }
           return null;
        }
     
        // 在主线程中,网络返回数据时运行
        @Override
        protected void onPostExecute(Bitmap result) {
           super.onPostExecute(result);
           if (result != null) {
               iv.setImageBitmap(result);
           }
        }
    }

    注意事项:


    为了正确的使用AsyncTask类,下面是几条必须遵守的准则:

    1) AsyncTask的实例必须在UI 线程中创建。

    2) execute方法必须在UI 线程中调用。

    3) 不要手动的调用onPreExecute(),onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法,须要在UI线程中实例化这个AsyncTask来调用。

    4) 该AsyncTask仅仅能被运行一次,否则多次调用时将会出现异常。

    5) doInBackground方法和onPostExecute的參数必须相应,这两个參数在AsyncTask声明的泛型參数列表中指定,第一个为doInBackground接受的參数,第二个为显示运行进度的參数,第第三个为doInBackground返回和onPostExecute传入的參数。


    Thread+Handler模式与AsyncTask的优缺点:


    AsyncTask实现的原理和适用的优缺点:

            AsyncTask,是android提供的轻量级的异步类,能够直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步运行的程度(能够通过接口实现UI进度更新),最后反馈运行的结果给UI主线程.

    使用的长处:

    1)        简单,快捷

    2)        过程可控     

    使用的缺点:

    1)        在使用多个异步操作和并须要进行Ui变更时,就变得复杂起来.

     

    Handler异步实现的原理和适用的优缺点:

            在Handler 异步实现时,涉及到 Handler,Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)执行并生成Message-Looper获取Message并传递给HandlerHandler逐个获取Looper中的Message,并进行UI变更。

    使用的长处:

    1)        结构清晰,功能定义明白

    2)        对于多个后台任务时,简单,清晰

    使用的缺点:

    1)         在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

    最后须要说明AsyncTask不能全然代替线程,在一些逻辑较为复杂或者须要在后台重复运行的逻辑就可能须要Thread+Handler来实现了。

           假设你认为这篇博文对你有帮助的话,请为这篇博文点个赞吧!也能够关注fengyuzhengfan的博客,收看很多其它精彩!http://blog.csdn.net/fengyuzhengfan/   

     

     

     

  • 相关阅读:
    使用 ASP.NET Core MVC 创建 Web API(五)
    使用 ASP.NET Core MVC 创建 Web API(四)
    使用 ASP.NET Core MVC 创建 Web API(三)
    使用 ASP.NET Core MVC 创建 Web API(二)
    使用 ASP.NET Core MVC 创建 Web API(一)
    学习ASP.NET Core Razor 编程系列十九——分页
    学习ASP.NET Core Razor 编程系列十八——并发解决方案
    一个屌丝程序猿的人生(九十八)
    一个屌丝程序猿的人生(九十七)
    一个屌丝程序猿的人生(九十五)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4079245.html
Copyright © 2011-2022 走看看