Handler
所有的思想设计都是源于生活高于生活。
大概知识点: 源码epoll 设计思路 设计模式 异步消息 同步消息 消息屏障 IntentServer
管理机制: 消息管理所有的消息
所有的代码都在handler中运行的。
MassegeQuaua 是变量 是共享内存的
注意看代码流程:
Looper.loop()–> next() 取消息—>msg.target.dispatchMessage(msg);说明Looper.loop() 在哪个地方调用执行。决定了handleMessage 就是在哪个线程中执行的。
// 这个handler 是在主线程中创建的,
这个Handler 的Looper 默认是getMainLooper()
所以它的Looper.loop() 是在主线程中执行的。
所以handleMessage 里面主线程中执行的。
Handler mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
Thread.dumpStack();
Log.i("fw", "handleMessage: "+ Looper.myLooper());
Log.i("fw", "handleMessage: "+ Looper.getMainLooper());
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler.sendEmptyMessage(0);}
// 结果:
2020-09-16 22:39:41.704 9700-9700/com.fengwei.generic I/fw: handleMessage: Looper (main, tid 2) {be2e8f1}
2020-09-16 22:39:41.704 9700-9700/com.fengwei.generic I/fw: handleMessage: Looper (main, tid 2) {be2e8f1}
// 主线程没有写Looper 用的就是ActivityThread 中默认的 getMainLooper() 主线程的Looper();
W/System.err: java.lang.Exception: Stack trace
W/System.err: at java.lang.Thread.dumpStack(Thread.java:1529)
W/System.err: at com.fengwei.generic.MainActivity$1.handleMessage(MainActivity.java:47)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err: at android.os.Looper.loop(Looper.java:223)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7523)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//这个线程和 2处 线程名字是一样的
Log.i("fw", "handleMessage: " + Thread.currentThread());
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
ServiceHandler mServerce = new ServiceHandler(Looper.myLooper());
mServerce.sendEmptyMessage(220);
//2
Log.i("fw", "Thread: " + Thread.currentThread());
Looper.loop();
// 由于上面的loop 是死循环 导致这里的语句是不会执行的
Log.i("fw", "Thread112: " + Thread.currentThread());
}
}).start();
}
HandlerThread 和 IntentService 是Handler的经典案例
static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
sWorkerThread.start();
}
static final Handler sWorker = new Handler(sWorkerThread.getLooper());
为什么要使用HandlerThread—> 它使用了是同步锁 保证getlooper 一定能够取到值,并且他的loop() 是在子线程中执行的。
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait(); // 等待并且释放锁
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();// 保证了mLooper 一定不会为空
notifyAll();// 不会释放锁,去唤醒wait()
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop(); // 这个是在子线程中执行的,
mTid = -1;
}
同步屏障
就在往消息队列里面添加一个target=null的messsage 作为屏障(注意这个屏障消息并没有设置setAsynchronous),当Loop轮询的时候,next获取消息的时候保证屏障消息后面的设置了(setAsynchronous(true)) 的异步消息优先执行。
使用反射来创建屏障消息:
private int postSyncBarrier(long when) {
// Enqueue a new sync barrier token.
// We don't need to wake the queue because the purpose of a barrier is to stall it.
synchronized (this) {
final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
msg.markInUse();
msg.when = when;
msg.arg1 = token;
Message prev = null;
Message p = mMessages;
if (when != 0) {
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
}
if (prev != null) { // invariant: p == prev.next
msg.next = p;
prev.next = msg;
} else {
msg.next = p;
mMessages = msg;
}
return token;
}
}
移除消息屏障:
public void removeSyncBarrier(int token) {