Android中的类

1.主线程的looper.loop()是个死循环,为什么ui线程不会出现anr。

首先,其次在ActivityThread中如果looper执行结束了,应用程序的主线程就结束。

anr核心也是通过looper处理超时消息来实现的。

就那广播的10s未执行完,然后出现anr这来举例。在发送广播的时候会发送一条广播消息,和一条延迟的广播超时消息,如果广播执行完成就从messagequeue中删除掉超时消息,此时程序正常运行。如果广播延迟消息发送就会执行anr相关代码。

具体可以看这个博客:https://blog.csdn.net/jackwang_dev/article/details/78287651

2.handler线程切换到主线程的原理是怎样?

核心思想就是通过共享变量进行消息处理。

主线程中的Looper.loop()方法是一个死循环,保证了程序不退出,能够一直从MessageQueue中取消息并处理(这都是发生在主线程)。在其他线程中只要能够向MessageQueue中添加消息(发生在其他线程),主线程在循环过程中取到消息做对应的处理,这个处理动作可以看成一个函数,主线程接到消息之后取执行对应的函数,那么这个函数执行的线程就是主线程了。

接下来看看我做的一个模拟,通过共享变量queue来切换线程执行。

package com.company;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class Test {
    public static void main(String[] args) {
        FHander hander = new FHander();
        hander.loop();
        new Thread(new Runnable() {
            @Override
            public void run() {
                hander.addMsage(Thread.currentThread().getName());
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                hander.addMsage("delay200 "+Thread.currentThread().getName());
            }
        },"线程1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                hander.addMsage(Thread.currentThread().getName());
            }
        },"线程2").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                hander.addMsage(Thread.currentThread().getName());
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                hander.addMsage("delay300 "+Thread.currentThread().getName());
            }
        },"线程3").start();
    }
}
class FHander{
    public static final Queue<String> queue = new ArrayBlockingQueue<String>(100);
    private boolean startLoop = false;
    public void loop(){
        if(startLoop){
            throw new RuntimeException("消息循环只开启一次就行");
        }
        startLoop = true;
        //如果这里不加线程,main方法就会卡死,在ActivityThrad中不用加线程,因为需要app不退出,
         new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    if(!queue.isEmpty()){
                        String  msg = queue.poll();
                        System.out.println("处理消息 thread = "+Thread.currentThread().getName()+"  msg = "+msg);
                    }
                }
            }
        },"MainThread").start();
    }
    public void addMsage(String s){
        System.out.println("添加消息线程为"+Thread.currentThread().getName());
        queue.add(s);
    }
}

执行结果是

添加消息线程为线程1
添加消息线程为线程2
处理消息 thread = MainThread  msg = 线程1
处理消息 thread = MainThread  msg = 线程2
添加消息线程为线程3
处理消息 thread = MainThread  msg = 线程3
添加消息线程为线程1
处理消息 thread = MainThread  msg = delay200 线程1
添加消息线程为线程3
处理消息 thread = MainThread  msg = delay300 线程3
 

代码简单的一皮,就是主线程开启死循环从queue中取数据然后做处理。然后开启其他线程来向queue中加数据。每加一个数字,就能切换到主线程中执行。

以上就是handler切换线程代码执行的原理。

3.WindowSession的作用是什么?

windowSession是一个binder,它是主线程和WMS(SystemService)沟通的binder,适用它可以在这两进程之间传递数据,比如windoSession.add()向WMS中添加window,另外一方面WMS处理事件消息的时候会根据消息句柄找到对应的window,传递给View。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值