"Android-事件处理机制"之面试必问技能点汇总

来源:互联网 发布:没有网络又可以玩游戏 编辑:程序博客网 时间:2024/06/08 19:33

  • 一Handler机制
    • 安卓把UI和耗时操作分在不同线程的原因
    • 逻辑
    • 完整的Handler机制参数的讲解
    • 可以再谈一下消息的回收机制
  • 二事件分发机制
  • 三主线程如何向子线程发送Message消息
      • 法1使用IntentService
      • 法2通过Handler和Looper发送

一.Handler机制

安卓把UI和耗时操作分在不同线程的原因:

  • 为了保证UI线程流程性
    • 手机显示的刷新频路:60Hz,即1秒60次,每16.67毫秒刷一次,为了不丢帧,那么主线程处理代码最好不要超过16毫秒.
    • 当子线程处理完耗时才走后,为了防止UI线程处理逻辑的混乱,就通过Handler来充当主线程和子线程间的桥梁.

逻辑:

  • 1.Handler在主线程Activity
  • 2.复写Handler的HandlerMessage方法
  • 3.子线程通过调用handler.sendMessage(),主线程就会执行HandlderMessage方法

完整的Handler机制,参数的讲解:

  • 1.除了Handler,Message,还有隐藏的Looper和MessageQueue对象
  • 2.主线程默认调用Looper.preper()方法;
    • 目的:在Looper里创建MessageQueue成员变量,且吧Looper对象绑定到当前线程
    • 当调用Handler 的sendMessage(对象)方法,就将Message对象添加到了Looper创建的MessageQueue队列中,同时给Message指定了target 对象.
      (PS:target对象就是 Handler 对象)
  • 3.主线程也默认执行Looper.looper()方法,该方法从Looper成员变量的MessageQueue中取出Message
    • 然后调用Message的targe对象的handleMessage()方法

(点击访问图解内容)

可以再谈一下消息的回收机制

(点击访问,内部是单链表结构)


二.事件分发机制

这个是面试必问的,也是我们必懂的,请大家点击专题访问学习.
(点击访问专题)

三.主线程如何向子线程发送Message消息?

法1:使用IntentService

  • 写一个类继承Intent服务,然后重写onHandleIntent(Intent intent)方法即可,该类中该方法是在子线程中.
  • 启动服务并传过来就是在子线程中获取信息了,然后还可再往当前主线程发消息谈Toast;
    (点击链接访问专题)

法2:通过Handler和Looper发送

  • 既然我们说Hander是主线程和子线程沟通的桥梁,那么Handler肯定有办法也能主传给子.
  • 具体逻辑是(和我们平时的正好相反,并且多加了Looper的3个方法):

    • 子线程:

      • 1.Looper准备
      • 2.新建Hander对象
      • (Looper.myLooper()为的是外部调用后能跳出消息循环)
      • 3.Looper让消息循环
    • onStart开启线程,然后点击1的时候主线程就往里发消息,点击2和销毁的时候跳出消息循环,预防内存泄露

  • 代码如下:

public class MainActivity2 extends Activity {    private Handler mMySubHandler;    private Looper  myLooper;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);    }    @Override    protected void onStart() {        super.onStart();        /**         *  当Activity启动的时候创建一个子线程,并启动         */        MyThread myThread = new MyThread();        myThread.start();    }    /**     * 绑定布局中的点击按钮,点击后给子线程发送消息     * @param view     */    public void click(View view) {        Message msg = new Message();        msg.obj = "MainActivity";        mMySubHandler.sendMessage(msg);    }    /**     * 按钮2,关闭子线程,让子线程退出     * 即让子线程的Looper对象退出即可,因为Looper.loop();是"线程阻塞"     */    public void click2(View view) {        if (myLooper != null) {//不是空证明还有,但要退出了            myLooper.quit();        }    }    @Override    protected void onDestroy() {        super.onDestroy();        //退出的时候也要释放,不然可能内存泄露        if (myLooper != null) {            myLooper.quit();        }    }    //子线程    class MyThread extends Thread {        @Override        public void run() {            //1.创建一个Looper对象            //(内部创建了MessageQueue,并将MessageQueue作为Looper对象的成员,然后将Looper对象绑定到ThreadLocal中,Handler思维)            Looper.prepare();            //创建Handler            mMySubHandler = new Handler(){                @Override                public void handleMessage(Message msg) {                    //处理主线程发送的消息                    System.out.println("接收到主线程发来的消息 : " + msg.obj);                }            };            //2.获取当前的Looper对象,myLooper为的是外部调用后能跳出消息循环            myLooper = Looper.myLooper();            //3.让消息循环起来            Looper.loop();            System.out.println("子线程退出");        }    }}
  • 运行结果:

点击1时

I/System.out: 接收到主线程发来的消息 : MainActivity

点击2时:

I/System.out: 子线程退出
0 0
原创粉丝点击