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/   

     

     

     

  • 相关阅读:
    maven .assembly
    命令参数解析库JCommonder
    OWL,以及XML,RDF
    Ambari是什么?
    上海新桥>风景服务区>宁波江东区车管所 及返程路线
    武汉旅游地图(zz)
    武汉旅游(zz)
    上海市松江区 <> 上海市金山区枫泾·万枫东路ab6177,racehttp://live.racingchina.com/
    明中路明华路到第九人民医院路线
    月台路春申塘桥到虹桥火车站
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4079245.html
Copyright © 2011-2022 走看看