• 【转】 Pro Android学习笔记(八九):了解Handler(3):延迟执行小例子


    目录(?)[-]

    1. 小例子
    2. Handler的处理
    3. Activity的代码片段
    4. 后台线程和UI的互动

      

    文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处:http://blog.csdn.net/flowingflying/

    之前我们介绍了Android主线程异步处理机制。通过Handler可以将消息放置到队列中等待处理。Handler可以控制消息放置在队列方式:sendMessage(), sendMessageAtFrontOfQueue(), sendMessageAtTime(), sendMessageDelayed()。在本例我们将利用sendMessageDelayed()实现一个延迟执行的小例子。

    小例子

    小例子很简单,UI见图。Activity的TextView可以显示Log信息(ADT中有时Log消息无法在LogCat中显示,LogCat觉得神啊神,不定会如何,所以也放在TextView中显示了)。点击OptionsMenu中的“Test Defered Handler”将会弹出一个Toast,用来模拟进行某些处理。和一般的触发不同,我们将延迟6秒才弹出框。

    如果我们在主线程中采用Sleep(6000)的方式,就会使主线程在6秒内无响应,如果点击完菜单,马上就去进行其他UI操作,就会触发ANR警告。我们利用Handler的sendMessageDelayed(),可以要求在6秒后,将信息放置在队列中,排队处理,很简单就能实现。但是在本例,我们将展现一个小技巧,利用Handler做一个时钟计数器,步长1秒,计数从0开始,到5时,触发toast。

    Handler的处理

    public class DeferWorkHandler extends Handler
        private int count = 0;  //计数器 
        private static final String DATE_MESSAGE="message";  //获取消息Data测试。消息中Data是Bundle 
        private MainActivity parentActivity = null;//记录主Activity,用于进行UI操作
         
        public DeferWorkHandler(MainActivity inputParent){
            parentActivity = inputParent; 
        } 
         
        @Override // 【4】消息处理触发handleMessage()回调消息,这是典型的异步处理方式。
        public void handleMessage(Message msg)
     {  
            printInfo("handleMessage() is called. count = " + count);
            printInfo("message's data : " + msg.getData().getString(DATE_MESSAGE));
            //如果计数为5,则进行处理,如果未满5,则延迟1秒后,将消息放入队列。 
            if(count >= 5){ 
                myWork(); 
                return ; 
            } 
            count ++;  
            sendTestMessage(1); 
        } 
        
        private void sendTestMessage(int secs){ 
            /*【1】 创建消息。通过handler将消息放入队列中,最好的方式是通过handler来获取消息,将自动完成消息和handler的关联,即可通过消息获得handler的参考,在处理消息时触发handler的回调函数handleMesage()。 obtainMessage()故名思议,不是创建,而是从全局的message池中获取,当消息处理完后,消息会被回收(环保啊)。 也可以用Message.obtain(handler,…)静态消息来获取。
           
    obtainMessage(); 
           obtainMessage(int what); 
           obtainMessage(int what, Object obj); 
           obtainMessage(int what, int arg1, int arg2); 
           obtainMessage(int what, int arg1, int arg2, Object obj); 
           如果消息存在跨进程的情况,Object obj要求采用Parcelable数据结构。一般而言更为便捷的方式通过setData()方式,如本例所采用的。如果只传递一些index用的整数,推荐利用arg1和arg2。
           what是开发者定制的消息code,在处理消息时用于标识是哪类消息,用于知晓如何解析消息。what、object、arg1、arg2都是message的public fields。*/
            Message msg = this.obtainMessage(); 
            //【2】设置消息的Data  
            Bundle b = new Bundle(); 
            b.putString(DATE_MESSAGE, "Hello world!"); 
            msg.setData(b); 
            // 【3】延期secs秒后将消息放入队列,handler还可以使用sendMessage()马上将消息放入队列中 
            sendMessageDelayed(msg, secs*1000); 
        } 
        
        public void doSomeDeferredWork(){ 
            printInfo("doSomeDeferredWork: something will be done later.");
            count = 0; 
            sendTestMessage(1); 
        } 

        private void myWork(){        
            printInfo("Something is doing now."); 
            Toast.makeText(parentActivity, "Something is doing now",Toast.LENGTH_LONG).show();
        } 
        
        private void printInfo(String s){  
            … … //在MainActivity和Logcat上显示信息 
        } 
        
    }

    Activity的代码片段

    private DeferWorkHandler  deferHandler = null; 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
        ... ... 
        if (id == R.id.menu_test_defered_handler) { 
             // 【0】创建Handler实例,由于在主Activity中创建,所以Handler中的handlerMessage()也将在主线程中执行。 
             if(deferHandler == null){ 
                 deferHandler = new DeferWorkHandler(this);  
             }          
             deferHandler.doSomeDeferredWork();  
             return true; 
        } 
        return super.onOptionsItemSelected(item); 

    后台线程和UI的互动

    在某些场景,我们在主线程中创建Handler对象,在其他线程中通过handler对象将消息放入队列,则仍将放入主线程队列中进行排队处理。如果其他后台线程需要在UI中进行处理,可以通过这种方式实现后台线程和UI之间的互动。

    相关小例子源代码可在Pro Android学习:了解Handler小例子中下载。

    相关链接: 我的Android开发相关文章

  • 相关阅读:
    haproxy redirect 重定向
    $res->header('Location')
    haproxy The Response line
    haproxy 配置和参数说明
    android应用中去掉标题栏的方法
    Linux 安装仿宋字体
    报表参数控件和报表内容自动居中设置方法
    zabbix 安装
    Chapter 2 Installing and Upgrading MySQL 安装和升级 MySQL
    将cantk runtime嵌入到现有的APP中
  • 原文地址:https://www.cnblogs.com/blongfree/p/5048092.html
Copyright © 2020-2023  润新知