• Android中AsyncTask与handler


    AsyncTask实际上就是一个线程池,AsyncTask在代码上比handler要轻量级别,而实际上要比handler更耗资源,因为AsyncTask底层是一个线程池!而Handler仅仅就是发送了一个消息队列,连线程都没有开。
    但是,如果异步任务的数据特别庞大,AsyncTask这种线程池结构的优势就体现出来了

     

    android的ui线程操作并不是安全的,并且和用户直接进行界面交互的操作都必须在ui线程中进行才可以。这种模式叫做单线程模式。

    我们在单线程模式下编程一定要注意:不要阻塞ui线程、确保只在ui线程中访问ui组件

    当我们要执行一个复杂耗时的算法并且最终要将计算结果反映到ui上时,我们会发现,我们根本没办法同时保证上面的两点要求;我们肯定会想到开启一个新的线程,让这个复杂耗时的任务到后台去执行,但是执行完毕了呢?我们发现,我们无法再与ui进行交互了。

    为了解决这种情况,android为我们提供了很多办法。

    1)、handler和message机制:通过显示的抛出、捕获消息与ui进行交互;

    2)、Activity.runOnUiThread(Runnable):如果当前线程为ui线程,则立即执行;否则,将参数中的线程操作放入到ui线程的事件队列中,等待执行。

    3)、View.post(Runnable):将操作放入到message队列中,如果放入成功,该操作将会在ui线程中执行,并返回true,否则返回false

    4)、View.postDelayed(Runnable, long)跟第三条基本一样,只不过添加了一个延迟时间。

    5)、android1.5以后为我们提供了一个工具类来搞定这个问题AsyncTask.

    AsyncTask是抽象类,定义了三种泛型类型 Params,Progress,Result。

    Params 启动任务执行的输入参数,比如HTTP请求的URL

    Progress 后台任务执行的百分比。

    Result 后台执行任务最终返回的结果,比如String

    用程序调用,开发者需要做的就是实现这些方法。

    1) 子类化AsyncTask

    2) 实现AsyncTask中定义的下面一个或几个方法

    onPreExecute(),该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。

    doInBackground(Params…),将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。

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

    onPostExecute(Result),在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.

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

    1) Task的实例必须在UI thread中创建

    2) execute方法必须在UI thread中调用

    3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params…), onProgressUpdate(Progress…)这几个方法

    4) 该task只能被执行一次,否则多次调用时将会出现异常

     

    package cn.com.chenzheng_java;   
             
        import android.os.AsyncTask;   
        /**  
         *   
         * @author chenzheng_java  
         * @description 异步任务AcyncTask示例  
         *      
         */  
        public class MyAsyncTask extends AsyncTask<String, Integer, Object> {   
             
         /**  
         * 该方法由ui线程进行调用,用户可以在这里尽情的访问ui组件。  
         * 很多时候,我们会在这里显示一个进度条啥的,以示后台正在  
         * 执行某项功能。  
         */  
         @Override  
         protected void onPreExecute() {   
         super.onPreExecute();   
         }   
             
         /**  
         * 该方法由后台进程进行调用,进行主要的耗时的那些计算。  
         * 该方法在onPreExecute方法之后进行调用。当然在执行过程中  
         * 我们可以每隔多少秒就调用一次publishProgress方法,更新  
         * 进度信息  
         */  
         @Override  
         protected Object doInBackground(String... params) {   
         return null;   
         }   
             
             
         /**  
         * doInBackground中调用了publishProgress之后,ui线程就会  
         * 调用该方法。你可以在这里动态的改变进度条的进度,让用户知道  
         * 当前的进度。  
         */  
         @Override  
         protected void onProgressUpdate(Integer... values) {   
         super.onProgressUpdate(values);   
         }   
             
         /**  
         * 当doInBackground执行完毕之后,由ui线程调用。可以在这里  
         * 返回我们计算的最终结果给用户。  
         */  
         @Override  
         protected void onPostExecute(Object result) {   
         super.onPostExecute(result);   
         }   
        }   

     

     

  • 相关阅读:
    数据库02
    MySQL1
    GIL 死锁 递归锁 event 信号量 线程Queue
    小脚本 暴力删除文件 刷屏
    常见web攻击 及基础 回顾(杂记)
    接口中的简单异步 async
    python协程 示例
    python 利用jinja2模板生成html
    python 调用webservices 接口
    python 进程 进程池 进程间通信
  • 原文地址:https://www.cnblogs.com/xuewater/p/2594823.html
Copyright © 2020-2023  润新知