为了账号安全,请及时绑定邮箱和手机立即绑定

Android面试常客Handler详解

难度中级
时长 2小时 0分
学习人数
综合评分9.30
169人评价 查看评价
9.7 内容实用
9.3 简洁易懂
8.9 逻辑清晰
  • 我想问一下,handler.removeMessages(),这个方法调用之后还是停不了handler??
    查看全部
  • 1.handler是android给我们提供用来更新UI的一套机制,也是一套消息处理的机制,我们可以发送消息,也可以通过它处理消息; 2.为什么要用handler,是因为android在设计的时候,就封装了一套消息创建、传递、处理机制,如果不遵循这样的机制就没有办法更新UI信息,就会抛出异常信息;
    查看全部
    0 采集 收起 来源:Handler是什么

    2015-08-07

  • 实现图片轮播效果
    查看全部
  • 重现
    查看全部
    0 采集 收起 来源:Handler是什么

    2015-08-05

  • 默认整个应用程序都是通过activityThread中创建,在这里面,会默认创建一个线程,也叫main线程,更新UI线程,就是通过这个main线程来创建的,在这个过程当中,会创建一个looper来创建,其中会创建一个messageQueue对象,
    查看全部
  • handler负责发送消息,Looper负责接收handler发送的消息,并直接把消息回传给相应的handler自己,同时messagequeue就是一个存储消息的容器。
    查看全部
  • 非UI线程真的不能更新UI吗? 是可以的。 (1)在线程中更新UI时会调用ViewParent.invalidateChild()方法检查当前的thread是否是UIthread。 final ViewParent p = mParent; if (p != null && ai != null && l < r && t < b) { final Rect damage = ai.mTmpInvalRect; damage.set(l, t, r, b); p.invalidateChild(this, damage); } 而ViewParent是一个接口类,其实现是ViewRootImpl,看invalidateChild()方法就可以看到会调用checkThread() void checkThread() { if (mThread != Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views."); } } (2)但是,ViewRootImpl这个类在activity的onResume()回调中创建。就算在子线程中更新UI,只要在ViewRootImpl创建之前更新UI,就可以逃避掉checkThread()的检查
    查看全部
  • 更新UI的4种方式: 1.通过Handle的post方法(); 2.调用Handle.sendMessage()方法;传统的方法 3.重写Activity中的runOnUIThread方法更新; 4.调用View自身的post(Runnable run)方法更新;
    查看全部
  • 非UI线程真的不能更新UI吗? 是可以的。 (1)在线程中更新UI时会调用ViewParent.invalidateChild()方法检查当前的thread是否是UIthread。 final ViewParent p = mParent; if (p != null && ai != null && l < r && t < b) { final Rect damage = ai.mTmpInvalRect; damage.set(l, t, r, b); p.invalidateChild(this, damage); } 而ViewParent是一个接口类,其实现是ViewRootImpl,看invalidateChild()方法就可以看到会调用checkThread() void checkThread() { if (mThread != Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views."); } } (2)但是,ViewRootImpl这个类在activity的onResume()回调中创建。就算在子线程中更新UI,只要在ViewRootImpl创建之前更新UI,就可以逃避掉checkThread()的检查。
    查看全部
  • 更新UI的4种方式(对应FifthActivity) 1.通过Handler的post()方法 mHandler.postDelayed(new Runnable() { public void run() { mTextView.setText("handler.post(Runnable)"); } }, 2000); 2.调用Handler.sendMessage()传统的方法 Message msg = new Message(); mHandler.sendMessageDelayed(msg, 2000); 配合handleMessage()使用。 3.重写Activity中的runOnUiThread()方法更新 runOnUiThread(new Runnable() { public void run() { mTextView.setText("runOnUiThread"); } }); 4.调用View自身的post(Runnable run)方法更新; mTextView.postDelayed(new Runnable() { public void run() { mTextView.setText("TextView.post()"); } }, 2000); 5. 以上四种更新UI的方式归根结底都是通过sendMessage()实现的。
    查看全部
  • handler.post(new Runnable() { 这里边重写其run函数,然后即可在其中执行耗时操作,然后给handler.sentMessage });
    查看全部
  • 主线程和子线程的信息交互(对应ForthActivity) 例子简单,不需要记录了,直接看一下eclipse的代码就行了。 需要注意: (1)mMainHandler.removeMessages(0)才可以取消消息。 (2)主线程创建了一个handler,但是它的Looper使用的是新创建的HandlerThread线程的looer,所以消息会发送到HandlerThread的消息队列中,并且在HandlerThread中的handleMessage处理。 (3)自己写了一个不停循环的计数程序,看eclipse
    查看全部
  • HandlerThread(对应ThirdActivity) 1. Handler在创建的时候可以指定Looper,这样通过Handler的sendMessage()方法发送出去的消息就会添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情况下,Handler绑定的是创建它的线程的Looper。 如果这个线程的Looper不存在,程序将抛出"Can't create handler inside thread that has not called Looper.prepare()"。 2. HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。 在其run()方法中,调用Looper.myLooper()获得一个looper对象。 synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); 在创建handler时使用getLooper()方法,其实现其实是一直等待looper对象的获得。 while (isAlive() && mLooper == null) { try { wait(); } } 3. HandlerThread的用处 创建Handler的时指定的looper,可以是别的线程创建的。所以Handler中MessageQueue的轮询不一定非要是创建Handler的线程进行,还可以在别的线程中进行。 这个时候我们就需要使用HandlerThread这个类来创建这个Looper了,这样消息的处理就在新创建的HandlerThread中进行。(如图) mThread = new HandlerThread("Handler Thread"); mHandler = new Handler(mThread.getLooper()){ public void handleMessage(android.os.Message msg) {... }; }; 同样需要注意:在新创建的ThreadThread中不能有更新UI的操作。
    查看全部
  • 自定义和线程相关的Handler(对应SecondActivity) 1. 使用方法: (1)定义MyThread class MyThread extends Thread{ public Handler handler; @Override public void run() { // TODO Auto-generated method stub Looper.prepare(); //准备looper对象 handler = new Handler(){ public void handleMessage(android.os.Message msg) { Log.i(TAG, "Current thread---> "+Thread.currentThread()); Toast.makeText(getApplicationContext(), "Current thread---> "+Thread.currentThread(), 1).show(); }; }; Looper.loop(); //轮询消息队列,发送给handler本身 } } (2)在UI线程中 mThread = new MyThread(); mThread.start(); mThread.handler.sendEmptyMessage(1); 2. UI线程(main线程)和非主线程的handler 在主线程中创建一个Handler,然后在主线程中调用mHandler.sendEmptyMessage(1)主线程就能收到消息,无需使用Looper,因为Looper默认就有。 注意: (1)在主线程中创建的Handler的handleMessage()方法不要写耗时的操作 (2)handler对象在哪个线程创建,消息就在那个线程处理。 (3)自己创建的MyThread中一定要准备Looper对象,并且要轮询消息队列Looper.loop() (4)自己创建的MyThread不是UI线程,所以不要有更新UI的操作
    查看全部
  • Handler与Looper、MessageQueue的关系(原理) (接上一笔记) 7. Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。 Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。 MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。 Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。 Thread:线程,负责调度整个消息循环,即消息循环的执行场所。 一下两篇文章讲的非常详细: http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html http://blog.csdn.net/mylzc/article/details/6736988 8. 图解(如图) 领导就是looper,我(handler)调用sendMessage()发送消息先经过他,他收到message之后调用Looper.loop()方法就将message又返回给我。我来handleMessage()。
    查看全部

举报

0/150
提交
取消
老师告诉你能学到什么?
通过本课程,你将学到: 1、什么是Handler 2、如何使用Handler 3、Handler的原理是什么 4、如何定义一个与线程相关的Handler 5、Android更新UI的几种方式 6、非UI线程真的不能更新UI吗 7、Handler使用过程中遇到的问题

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!