
我是蒼王,以下是我這個(gè)系列的相關(guān)文章,有興趣可以參考一下,可以給個(gè)喜歡或者關(guān)注我的文章。
[Android]如何做一個(gè)崩潰率少于千分之三噶應(yīng)用app--章節(jié)列表
有一定開發(fā)經(jīng)驗(yàn),大家應(yīng)該對(duì)Handler的機(jī)制有非常深刻的了解,Handler在Android開發(fā)中被廣泛用于線程間通信。
近來遇到了一個(gè)問題,在view init的情況下使用view自身的handler會(huì)崩潰,但是直接使用postDelay卻能正常運(yùn)行。
這里需要思考幾個(gè)問題
1.view的handler是從哪里來的呢?
2.view的handler為何會(huì)崩潰?
3.View的post的運(yùn)行機(jī)制是?
讀了這篇文章,你就能理解到這些問題
1.view的handler是從哪里來的呢?
public Handler getHandler() {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler;
}
return null;
}
可以看到是handler是從mAttachInfo過來的.
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
mAttachInfo = info;
……
在dispatchAttachedToWindow的時(shí)候來傳遞過來,而viewgroup中觸發(fā)這個(gè)傳遞操作。
這里最終會(huì)在ViewRootImpl中創(chuàng)建出來AttachInfo對(duì)象。
而handler是來自于自定義的ViewRootHandler,那就可以知道,整個(gè)Activity的View系統(tǒng)共用一個(gè)Handler是由ViewRootImpl創(chuàng)建,用于處理頁面視圖事件等處理。
2.view的handler為何會(huì)崩潰?
dispatchAttachedToWindow是在View調(diào)用init初始化之后的,handler還沒有被初始化,所以就導(dǎo)致handler返回null對(duì)象出外,如果不判空就會(huì)崩潰了。
3.View的post的運(yùn)行機(jī)制是?
可以看到當(dāng)mAttachInfo未初始化的時(shí)候,會(huì)先將runnable塞到一個(gè)隊(duì)列當(dāng)中。
public boolean postDelayed(Runnable action, long delayMillis) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.postDelayed(action, delayMillis);
}
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().postDelayed(action, delayMillis);
return true;
}
當(dāng)view被綁定到窗口的時(shí)候,會(huì)將隊(duì)列和handler綁定,然后啟動(dòng)隊(duì)列任務(wù)
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
……
// Transfer all pending runnables.
if (mRunQueue != null) {
mRunQueue.executeActions(info.mHandler);
mRunQueue = null;
}
……
}
public void executeActions(Handler handler) {
synchronized (this) {
final HandlerAction[] actions = mActions;
for (int i = 0, count = mCount; i < count; i++) {
final HandlerAction handlerAction = actions[i];
handler.postDelayed(handlerAction.action, handlerAction.delay);
}
mActions = null;
mCount = 0;
}
}