Android的Handler原理源码仿写及handler

转载地址 Java版Handler源码仿写

Handler里面有五个重要的类 Handler,Looper,MessageQueue,Message,ThreadLocal
Handler:用来转换线程处理的
Looper:用来调用MessageQueue,查询是否有新的Message
MessageQueue:用来存储Message的
Message:用来存储信息和当前Handler对象
ThreadLocal:里面有一个Map集合,存储Thread和Looper

public class Main {  
  
    public static void main(String[] args) {  
  
        new Main().start();  
          
    }  
      
    private void start(){  
          
        Looper.prepare();  
  
        onCreate();  
          
        //死循环,阻塞式  
        Looper.loop();  
          
        //下面 的代码通常不会执行  
        System.out.println("exit........");  
        throw new RuntimeException("Main thread loop unexpectedly exited");  
  
    }  
    private void onCreate() {  
        //  
        // 下面的操作相当于运行在android的UI线程中   
        //  
  
        final Thread thread = Thread.currentThread();  
        System.out.println("main thread=" + thread);  
  
        Handler handler = new Handler() {  
            @Override  
            public void handleMessage(Message msg) {  
                //若thread == Thread.currentThread(),则证明已经运行在主线程中了  
                System.out.println("current thread is main thread? " + (thread == Thread.currentThread()));  
                System.out.println(msg);  
                System.out.println();  
            }  
        };  
        // 测试1       主线程创建handler,子线程使用该handler发送消息   
        new Thread() {  
            public void run() {  
                try {//模拟耗时操作  
                    Thread.sleep(1000 * 2);  
                } catch (InterruptedException e) {  
                }  
                Message message = new Message();  
                message.obj = "new Thread" + Thread.currentThread();  
                message.what = (int) System.currentTimeMillis();  
                //在子线程中发送消息   
                handler.sendMessage(message);  
                  
                try {  
                    Thread.sleep(1000 * 2);  
                } catch (InterruptedException e) {  
                }  
                  
                message = new Message();  
                message.obj = "hanler...waht==1" ;  
                message.what = 1;  
                //在子线程中发送消息   
                handler.sendMessage(message);  
                  
  
                message = new Message();  
                message.obj = "hanler...waht==2" ;  
                message.what = 2;  
                //在子线程中发送消息   
                handler.sendMessage(message);  
                  
                message = new Message();  
                message.obj = "hanler...waht==3" ;  
                message.what = 3;  
                //在子线程中发送消息   
                handler.sendMessage(message);  
                  
            };  
        }.start();  
  
        // 测试2 在thread内部创建handler,结果会抛出异常  
        new Thread() {  
            public void run() {  
                try {  
                    sleep(1000 * 3);  
                } catch (InterruptedException e) {  
                }  
                /* 
                 * 在线程内部使用默认构造函数创建handler会抛出异常。 
                 * android中也可以在子线程中创建Handler,但要在初始化时传入Looper, 
                 * Looper.getMainLooper()获取到的就是主线程的Looper,所以可以这样创建 
                 *  
                 * new Handler(Looper.getMainLooper()){ 
                        @Override 
                        public void handleMessage(Message msg) { 
                            //运行在主线程中 
                        } 
                    }; 
                 */  
                Handler h = new Handler() {  
                    public void handleMessage(Message msg) {  
  
                        System.out.println("haneler msg...." + msg);  
                    };  
                };  
  
                Message message = new Message();  
                message.obj = "handler in new Thread";  
                message.what = (int) System.currentTimeMillis();  
                //在子线程中发送消息   
                h.sendMessage(message);  
  
            };  
        }.start();  
  
        //  
        // 上面的操作相当于运行在android的UI线程中   
        //  
  
    }  
}  
public class Handler {  
  
  
    private MessageQueue messageQueue;  
      
    public Handler() {  
  
        Looper looper=Looper.myLooper();  
          
        if (looper==null) {  
             throw new RuntimeException(  
                        "Can't create handler inside thread that has not called Looper.prepare()");  
                 
        }  
          
        this.messageQueue=looper.messageQueue;  
    }  
  
    public void sendMessage(Message msg) {  
          
        //Looper循环中发现message后,调用message.targer就得到了当前handler,使用taget.handleMessage  
        //就把消息转发给了发送message时的handler的handleMessage函数  
        msg.target=this;  
          
        messageQueue.enqueueMessage(msg);  
          
    }  
      
    public void handleMessage(Message msg) {  
    }  
}  


public class Looper {  
    private static final ThreadLocal<Looper> threadLocal=new ThreadLocal<>();  
    /** 
     * 存储Message的队列,阻塞式,没有消息则一直等待 
     */  
    final MessageQueue messageQueue;  
      
      
    private Looper() {  
        messageQueue=new MessageQueue();  
    }  
  
    /**为该线程创建Looper, 
     * 若该线程已经有Looper了则不需要再次调用prepare 
     */  
    public  static void prepare() {  
        if (threadLocal.get() != null) {  
            throw new RuntimeException("Only one Looper may be created per thread");  
        }  
        threadLocal.set(new Looper() );  
    }  
      
    public static void loop() {  
        Looper looper=myLooper();  
        if (looper == null) {  
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");  
        }  
        MessageQueue messageQueue=looper.messageQueue;  
          
        for(;;){  
            Message message=messageQueue.next();  
            message.target.handleMessage(message);  
        }  
    }  
      
    /** 
     * 获取当先线程的Looper 
     * @return 
     */  
    public static Looper myLooper() {  
        return threadLocal.get();  
    }  
}  
public class MessageQueue {  
  
  
    private BlockingQueue<Message>blockingQueue=new LinkedBlockingQueue<>();  
      
    /** 
     * 阻塞式,没有消息则一直等待 
     * @return 
     */  
    public Message next() {  
        try {  
            return blockingQueue.take();  
        } catch (InterruptedException e) {  
            throw new RuntimeException();  
        }  
    }  
      
    /** 
     * 插入到消息队列尾部 
     * @param message 
     */  
    void enqueueMessage(Message message) {  
        try {  
            blockingQueue.put(message);  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    }  
}  
public class ThreadLocal<T> {  
  
  
    private Map<Thread,T>map;  
  
    public ThreadLocal() {  
        map=new HashMap<>();  
    }  
      
    public void set(T obj) {  
        map.put(Thread.currentThread(),obj);  
    }  
      
    public T get() {  
        return map.get(Thread.currentThread());  
    }  
      
}  
public class Message {  
  
    Handler target;  
    public Object obj;  
    public int what;  
  
    @Override  
    public String toString() {  
        return   "what="+what+" obj="+obj.toString();  
    }  
      
}  

IdleHandler

一般用来当线程空闲时执行任务     空闲条件(没有要处理的任务,或者最近的任务不需要马上执行)
可以用来预缓存网络数据或者预加载某些资源
需要注意的是:
1.执行时间非常的不确定
2.如果是主线程的话,最好不要执行耗时任务, 虽然试过可以耗时超过5s以上,但是会造成UI刷新卡顿等问题

Choreographer
Choreographer 可以认为是连接底层和应用层的中间人角色。对下,它负责注册并接收底层发送的 Vsync 信号;对上,负责在应用层协调下一帧的绘制、事件、动画过程。Choreographer 配合 SurfaceFlinger、Triple Buffer 为 Android 系统提供稳定的帧率刷新环境。

内部实现了,view的绘制,动画执行,触摸事件的响应    动画不流畅时跳帧等实现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值