zoukankan      html  css  js  c++  java
  • Android学习笔记十:异步处理

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7520700.html

        一:基础概念

        UI线程:当Android程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件、屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。主线程通常又被称为UI线程,Android只允许UI线程修改Activity里的UI组件。

        子线程:在程序的activity中创建、启动的线程为子线程,子线程中不能操作UI组件。

        后台任务:后台任务一般用子线程来完成,通常用于执行一些耗时任务如:复杂计算、下载文件等。因为这些操作是与UI线程同时运作的,所以又称为异步操作。

        二:异步方式之——消息传递机制

        我们知道,只有UI线程才能修改、操作界面组件,那么其他子线程中的信息如何反映到UI中呢?那就需要子线程把信息汇总到UI线程,由UI线程显示到组件上。

        这个过程,就是消息传递机制。

        1)消息传递机制原理图

        

        2)消息传递机制解释

        首先,UI线程中维护一个消息队列MessageQueue、一个循环者Looper、一个处理者Handler:消息队列负责接受、存储其他子线程发送过来的消息,等待UI线程处理;循环者不停地轮询消息队列,每次都提取队首一个消息;处理者负责处理Looper提取出来的消息,并负责把结果在UI进行呈现。其中,MessageQueue和Looper随着UI线程启动而自动创建并运行,Handler则需要手动定义

        其次,在UI线程中创建并启动子线程,子线程中通过同一个handler(通常这个handler为acticity代码中的全局变量,因此子线程中可见)来发送消息,从而把消息发送到了当前UI线程的handler对应的消息队列中。

        3)实现步骤

        根据消息传递机制的原理,我们只需针对实现各个环节需要的东西即可。

        首先:定义、创建Handler,重写其中的handlerMessage方法,处理消息

    private Handler mHandler = new Handler() {  
            @Override  
            public void handleMessage(Message msg) {  
                switch (msg.what) {  
                    //根据消息内容,作处理
                }  
            }  
        };  

        然后:定义子线程,在其中定义发送消息语句

     Runnable runnable = new Runnable() {  
            @Override  
            public void run() {  
                Message message = new Message();  
                message.what = 消息标签;  
                mHandler.sendMessage(message);  //handler是UI线程中的handler
            }  
        };  

        最后:根据条件,创建子线程实例并启动

    mThread = new Thread(runnable);  
    mThread.start();  

        4)应用场景

        Handler机制适合多个子线程存在的情况,这样可以把多个子线程发送过来的信息在UI线程中统一处理、绘制呈现。

       【附:如果需要在子线程中使用handler和looper,则需要获取到UI线程中的handler、looper对象。具体方法见:http://blog.csdn.net/logicteamleader/article/details/46591499

        三:单个异步任务——AsyncTask

        消息传递机制看起来比较复杂,涉及到了消息队列的应用,这几乎是大型Web应用的架构层面才会用到的模式了。

        如果只是单个的异步任务,用消息传递机制就有些过于麻烦了,为此,Android为我们提供了一个辅助类——AsyncTask。

        AsyncTask类,可以理解为异步任务执行者;这个类的设计目的很明确,就是为了“执行一个较为耗时的异步任务(最多几秒钟),然后更新界面”。

        1:使用AsyncTask

        1)继承AsyncTask,定义子类,重写其中的几个方法:

         AsyncTask需要重写5个方法,分别是:

        1、onPreExecute方法:准备运行,该回调函数在任务被执行之后立即由UI线程调用,一般可以显示进度条。

        2、doInBackground(Params ...)方法:正在后台运行,通常在这里执行耗时的后台计算,计算结果返回给函数,这里如果AsyncTask的第三个参数是Void的话不需要返回,这里不能更新UI,但是可以调用publishProgress(Progress ...)方法完成。

        3、onProgressUpdate(Progress ...)方法:进度更新,UI线程在publishProgress(Progress ...)方法调用完成后被调用,一般动态显示一个进度。

        4、onPostExecute(Result)方法:完成后台任务,会返回,这里可以进行些UI的操作,比如提醒任务执行的结果,以及关闭掉进度条对话框等。

        5、onCancelled方法:取消任务,在调用AsyncTask的cancel()方法的时候调用。

    class ViewContentTask extends AsyncTask<Void, Integer, Boolean> {//三个范型分别对应下面doInBackground、onProgressUpdate、onPostExecute三个方法的参数类型
            @Override  
            protected Boolean doInBackground(Void... voids) {  
                return null;  
            }  
      
            @Override  
            protected void onProgressUpdate(Integer... values) {  
            }  
      
            @Override  
            protected void onPostExecute(Boolean b) {  
                //操作UI组件  
            }  
      
            @Override  
            protected void onPreExecute() {  
            }  
      
            @Override  
            protected void onCancelled() {  
            }  
        }  
      

        2)创建异步任务实例,启动异步任务

    ViewContentTask  task = new ViewContentTask();  
    task.execute();  

        2:AsyncTask工作原理

        当一个异步任务被执行时,要经历四步: 
        onPreExecute(),在UI线程中执行,它会在异步任务开始前执行,一般用来设置任务参数; 
        doInBackground, 最重要的方法,在子线程中执行(事实上,只有它在子线程中执行,其他方法都在UI线程中执行)。当onPreExecute结束后,本方法立刻执行,它用   来进行后台的耗时计算,异步任务的参数会被传给它,执行完成的结果会被送给第四步;执行途中,它还可以调用publishProgress 方法来通知UI线程当前执行的进度; 
        onProgressUpdate, 当publishProgress 被调用后,它在UI线程中执行,刷新任务进度,一般用来刷新进度条等UI部件; 
        onPostExecute, 当后台的异步任务完成后,它会在UI线程中被调用,并获取异步任务执行完成的结果。

        

  • 相关阅读:
    HBase目录
    HBase介绍及简易安装(转)
    Hadoop目录
    通过java读取HDFS的数据 (转)
    Flume-NG一些注意事项(转)
    spark读取 kafka nginx网站日志消息 并写入HDFS中(转)
    Java开发牛人十大必备网站
    HTTP协议状态码详解(HTTP Status Code)(转)
    Flume NG 配置详解(转)
    Android笔记(五)利用Intent启动活动
  • 原文地址:https://www.cnblogs.com/ygj0930/p/7520700.html
Copyright © 2011-2022 走看看