1.Activity間的跳轉(zhuǎn)耗時接近兩秒了
2.可以發(fā)現(xiàn),紅框中的就是自己項目中的代碼蒿褂,耗時占了總耗時的73.9%
3.在項目中修改后達(dá)到了可接受的打開時間
4.往空閑消息隊列中添加信息圆米,這類信息會在主線程空閑時才會被取出來處理,一般用在Activity的初始化方法onCreate()中啄栓,在queueIdle()方法添加不會回影響Activity正常初始化的耗時操作娄帖,此方法返回false會在執(zhí)行完后把這個消息從空閑消息隊列中刪除
在Activity的onCreate()方法中
Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler(){
@Override
public boolean queueIdle() {
//微信,qq分享輔助類的初始化就是一個耗時操作昙楚,里面涉及到了反射
WXUtil.regToWx(context);
mTencent = Tencent.createInstance(Constant.QQ_APP_ID, getApplication());
return false;
}
});
擴(kuò)展:源碼閱讀(MessageQueue的next():消息循環(huán))
Message next() {
// 當(dāng)消息循環(huán)已經(jīng)退出或被釋放的時候近速,直接返回null
// 如果應(yīng)用程序在退出后嘗試重新啟動一個looper,就可能會發(fā)生這種情況
final long ptr = mPtr;
if (ptr == 0) {
return null;
}
int pendingIdleHandlerCount = -1; // -1 only during first iteration
int nextPollTimeoutMillis = 0;
for (;;) {//死循環(huán)
//將當(dāng)前線程中的任何阻塞的binder命令刷新到cpu中執(zhí)行堪旧,在執(zhí)行可能導(dǎo)致長時間阻塞的操作前調(diào)用是非常有用的削葱,可以確保任何掛起的對象引用被釋放,防止進(jìn)程持有一個對象的時間超過它所需要的
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
//消息死循環(huán)不會崩潰的原因
nativePollOnce(ptr, nextPollTimeoutMillis);
//同步代碼塊
synchronized (this) {
// 嘗試檢索下一條信息淳梦,如果有就返回
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
if (msg != null && msg.target == null) {
// Stalled by a barrier. 在消息隊列中查找下一個異步消息
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
//如果下一條消息尚未準(zhǔn)備好析砸。設(shè)置超時喚醒
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// 如果準(zhǔn)備好了就獲取消息.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;
}
} else {
// 沒有異步消息了
nextPollTimeoutMillis = -1;
}
// Process the quit message now that all pending messages have been handled.
if (mQuitting) {
dispose();
return null;
}
// 如果第一次空閑,則獲取可運行消息數(shù)
// 空閑消息只會在消息隊列為空或者隊列第一個消息將要被處理時處理
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run. Loop and wait some more.
mBlocked = true;
continue;
}
if (mPendingIdleHandlers == null) {
//容量只有四個
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
}
// Run the idle handlers.
//只有在第一次迭代中才到達(dá)這個代碼塊
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
mPendingIdleHandlers[i] = null; // release the reference to the handler
boolean keep = false;
try {
keep = idler.queueIdle();
} catch (Throwable t) {
Log.wtf(TAG, "IdleHandler threw exception", t);
}
if (!keep) {
synchronized (this) {
//當(dāng)返回值keep為false時爆袍,從空閑列表中移除
mIdleHandlers.remove(idler);
}
}
}
// 保證了空閑列表中的消息只處理一次.
pendingIdleHandlerCount = 0;
// 在調(diào)用空閑處理程序時首繁,可能已經(jīng)傳遞了一個新消息作郭,因此可以返回并再次查找掛起的消息,而不必等待
nextPollTimeoutMillis = 0;
}
}