目录(?)[-]

  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开发相关文章

【转】 Pro Android学习笔记(八九):了解Handler(3):延迟执行小例子的更多相关文章

  1. 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...

  2. 【转】 Pro Android学习笔记(九四):AsyncTask(3):ProgressDialog

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

  3. 【转】 Pro Android学习笔记(九二):AsyncTask(1):AsyncTask类

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在Handler的学习系列中,学习了如何h ...

  4. 【转】 Pro Android学习笔记(九三):AsyncTask(2):小例子

    目录(?)[-] 继承AsyncTask UI操作接口 使用AsyncTask 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn. ...

  5. 【转】Pro Android学习笔记(九):了解Content Provider(下下)

    Content provider作为信息的读出,比较常见的还有文件的读写,最基础的就是二进制文件的的读写,例如img文件,音频文件的读写.在数据库中存放了该文件的路径,我们可以通过ContentPro ...

  6. 【转】 Pro Android学习笔记(九一):了解Handler(5):组件生命

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

  7. 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView

    目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...

  8. 【转】 Pro Android学习笔记(八二):了解Package(1):包和进程

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在之前,我们已经学习了如何签发apk,见P ...

  9. 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge

    目录(?)[-] xml控件代码重用include xml控件代码重用merge 横屏和竖屏landsacpe portrait xml控件代码重用:include 如果我们定义一个控件,需要在不同的 ...

  10. Pro Android学习笔记 ActionBar(1):Home图标区

     Pro Android学习笔记(四八):ActionBar(1):Home图标区 2013年03月10日 ⁄ 综合 ⁄ 共 3256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 ActionBar在A ...

随机推荐

  1. C++逗号表达式

    c++中,逗号表达式的结果是最右边表达式的值

  2. 如何使用REST请求风格

    REST:即 Representational State Transfer.(资源)表现层状态转化.是目前最流行的一种互联网软件架构. 它结构清晰.符合标准.易于理解.扩展方便, 所以正得到越来越多 ...

  3. HBase-协处理器详解及实现

    协处理器(coprocessor) 把一部分计算移动到数据的存放端. 实例:HBase添加solr二级索引详细代码 简介 协处理器允许用户在region服务器上运行自己的代码,允许用户执行region ...

  4. 在python3.x上安装suds 并访问webservice

    suds...py3很乱.. 一开始直接使用命令行:pip install suds安装,结果报错ImportError: No module named client,然后就自然的pip insta ...

  5. jquery下json数组的操作用法实例

    jquery下json数组的操作用法实例: jquery中操作JSON数组的情况中遍历方法用的比较多,但用添加移除这些好像就不是太多了. 试过json[i].remove(),json.remove( ...

  6. JAVA设计模式初探之组合模式

    先看看组合模式的定义吧:“将对象组合成树形结构以表示‘部分-整体’的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性.” 就拿剪发办卡的事情来分析一下吧. 首先,一张卡可以在总部,分店, ...

  7. 继续吐槽XE5中的boost::thread问题:找不到CC32130MT.DLL

    在XE5中,随便创建一个HelloWorld程序,加入boost::thread的功能,编译链接后,无法运行,无法调试,提示找不到CC32130MT.DLL 这个DLL名字看上去好像是跟多线程有关的, ...

  8. CSS媒体查询 width VS device-width

    In CSS media the difference between width and device-width can be a bit muddled, so lets expound on ...

  9. eclipse部署和启动guns

    eclipse部署guns: 1.import -> 搜索maven -> Existing Maven Projects -> 选择guns根目录 2.修改配置文件: spring ...

  10. MySQL 约束和数据库设计

    1.MySQL 约束: 1.约束的概念: 约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性.唯一性. MySQL中,常用的几种约束: 约束类型: 非空 主键 唯一 外键 默认值 ...