android Handler介绍(二)

从上一节的内容可以看到,handler负责发送消息到android内部提供的消息队列中,然后在一定的时机从消息队列将消息取出进行处理。出于安全性和偶合性的考虑,handler并不直接与消息队列进行交互,而上通过一个名为Looper的类来负责交互。

上一节讲解的handler的用法全部都上在主线程上进行的。如果我们需要处理比较耗时的事情,就不能把handler放在主线程中了。

线程在默认的时候是没有Looper与之相关联。在线程中,我们可以通过调用prepare 方法来启动一个消息loop,调用loop方法来通知Looper来处理消息,直至结束。Looper提供了很多的静态方法来与线程、消息队列进行交互。一个线程最多允许创建一个Looper

以下是SDK文档中介绍的在线程中使用handler的一种方法:

class LooperThread extends Thread {

   public Handler mHandler;

        public void run() {

            Looper.prepare();

            mHandler = new Handler() {

                public void handleMessage(Message msg) {

                    // process incoming messages here

                }

            };

            Looper.loop();

        }

有一个特例, 当应用程序的进程创建时,主线程会启动一个消息队列和Looper,并通过该队列管理一些优先级别比较高的对象(如Activity 等)。

考虑以下情况,定义一个全局变量mHandler

       mRunnable = new  Runnable(){

           @Override

           public void run() {

              // TODO Auto-generated method stub    

              String s = mHandler.getLooper().getThread().getName();

              Log.e("minrui", s);

              mHandler.postDelayed(mRunnable, 1000);

           }};

Thread t  = new Thread(mRunnable,"malone");

        t.start();

我们创建一个名为“malone”的线程,并启动,在其Runnable接口的run方法中通过handler发送消息,并打印出与该handler相关联的looper所在的线程的名字。

打印结果如下:

ERROR/minrui(1630): main

结果似乎有点出人意料,但是仔细分析,启动的名为“malone”的线程并未与一个looper相关联,并且handler中的looper是与主线程关联的,结果确实应该是这样。

那么,可不可以在主线程中定义handler,在代码中动态改变handler使之与其他线程的looper相关联呢?看以下的例子:

mRunnable = new  Runnable(){

              @Override

              public void run() {

                  // TODO Auto-generated method stub

                  Looper.prepare();

                  mHandler = new Handler(Looper.myLooper());

                  String s = mHandler.getLooper().getThread().getName();

                  Log.e("minrui", s);

                  mHandler = new Handler(Looper.getMainLooper());

                   s = mHandler.getLooper().getThread().getName();

                  Log.e("minrui", s);        

              }};

    Thread t  = new Thread(mRunnable,"malone");

            t.start();

结果打印如下:

ERROR/minrui(4049): malone

ERROR/minrui(4049): main

Android提供了一个包含looperthread类,这个类的名字叫HandlerThread,我们看一下这个类的用法:

t = new HandlerThread("malone123");

        t .start();

        mHandler1 = new Handler(t.getLooper());

        mHandler1.post(new  Runnable(){

           @Override

           public void run() {

              // TODO Auto-generated method stub

              String s = mHandler1.getLooper().getThread().getName();

              Log.e("minrui", s);

           }

        });

打印结果如下:

ERROR/minrui(3528):  malone123

有一点值得注意的是:

android2.1之前,android认为在非线程中操作UI界面是不安全的,因此禁止在其它线程中修改UI界面。解决的方法有两种,一是通过在主线程中定义的handler更新界面,二是直接调用被修改的viewpostInvalidate方法刷新单个view

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值