如何分析源码
1,明白初步原理
2,找到切入点
3,找到关键对象
4,分析对象之间的关系
5,分析当中所有的设计模式
6,为什么这么用,解决了什么问题
7,在这种应用场景下分析他们的优劣,从而得到框架思维能力
为什么要用handler?
1,解决线程同步的问题而产生。
2,如果一个耗时任务在主线程种操作,那么就会出现界面假死(ANR),也就是android的卡顿,所以Android强调在进行耗时操作的时候需要对耗时代码分流到线程当中完成,但是面临一个问题,我的这些操作完成之后,我是否需要得到通知?
3,handler 可以很好的处理这些工 作。
4,handler 是google Android工程师为我们设计好的处理高并发的工具类,这个工具类就是用于线程间通信的。所以我们压根不需要取管什么多线程,直接在手机上面用就好了
Handler的使用:
主线程的looper是在ActivtiyThread中创建的,通过Looper.prepareMainLooper()创建,Looper.loop()执行死循环从MessageQueue中取得数据。
**
* Created by zqb on 2019/6/11
*/
public class Handler {
private MessageQueue mQueue;
private Looper mLooper;
public Handler() {
mLooper=Looper.getLooper();
mQueue=mLooper.mQueue;
}
/**
* 发送消息
*
*/
public void sendMessage(Message msg){
//消息信息持有Handler对象,消息蕴含了发送者的信息
msg.mTarget=this;
//把消息添加到队列中
mQueue.enqueueMessage(msg);
}
/**
* 分发消息
*/
public void dispatchMessage(Message msg){
handlerMessage(msg);
}
public void handlerMessage(Message msg){
}
}
ThreadLocal是一个关于创建线程局部变量的类。
通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。
/**
* Created by zqb on 2019/6/11
*/
public class Looper {
private static ThreadLocal<Looper> sThreadLocal=new ThreadLocal<>();
public MessageQueue mQueue;
private Looper() { //一个looper 有一个队列
mQueue=new MessageQueue();
}
/**
* 初始化looper
*/
public static void prepare(){
if(sThreadLocal.get()!=null){
throw new RuntimeException("一个线程只能有一个Looper");
}
sThreadLocal.set(new Looper());
}
public static Looper getLooper(){
return sThreadLocal.get();
}
public static void loop(){
Looper looper = getLooper();
MessageQueue queue = looper.mQueue;
for (;;){//死循环获取队列中的数据
Message msg = queue.next();
if(msg==null){
continue;
}
//消息持有发送者
msg.mTarget.dispatchMessage(msg);
}
}
}
/**
* Created by zqb on 2019/6/11
*/
public class MessageQueue {
//互斥锁
private Lock mLock;
private Condition mNotEmpty;
private Condition mNotFull;
private Message[] mItems;
int putIndex = 0;
int takeIndex = 0;
int count =0;
public MessageQueue() {
mItems = new Message[50];
mLock= new ReentrantLock();
mNotEmpty=mLock.newCondition();
mNotFull=mLock.newCondition();
}
/**
* 入队 生产者
*
* @param msg 消息
*/
public void enqueueMessage(Message msg) {
try {
mLock.lock();
//如果满了 锁死不让进入
while (count==mItems.length){//为了多个子线程唤醒,多个子线程可能存在堵塞
try {
//等待唤醒
mNotEmpty.await();
}catch (Exception e){
e.printStackTrace();
}
}
mItems[putIndex] = msg;
putIndex = (++putIndex == mItems.length) ? 0 : putIndex;
count++;
//加入消息唤醒出队
mNotFull.signalAll();
}finally {
mLock.unlock();
}
}
/**
* 出队 消费者
*/
public Message next() {
try {
mLock.lock();
while (count==0){
try {
mNotFull.await();
}catch (Exception e){
e.printStackTrace();
}
}
Message msg = mItems[takeIndex];
takeIndex = (++takeIndex == mItems.length) ? 0 :takeIndex;
count--;
//出去消息唤醒入队
mNotEmpty.signalAll();
return msg;
}finally {
mLock.unlock();
}
}
}
/**
* Created by zqb on 2019/6/11
*/
public class Message {
public Handler mTarget;
public int what;
public Object obj;
}
public class HandlerTest {
public static void main(String[] args){
Looper.prepare();
final Handler handler=new Handler(){
@Override
public void handlerMessage(Message msg) {
System.out.println("线程ID:"+Thread.currentThread()+"-s-message:"+msg.obj);
}
};
new Thread(){
@Override
public void run() {
for (int i = 0; i < 10; i++) {
Message msg=new Message();
msg.obj= UUID.randomUUID();
System.out.println("线程ID:"+Thread.currentThread()+"--message:"+msg.obj);
handler.sendMessage(msg);
}
}
}.start();
Looper.loop();
}
}