1. activity的啟動流程怯疤?
lanuch ->actvitymange->activitymagerservice(ActivityManagerService(AMS)負(fù)責(zé)系統(tǒng)中四大組件的啟動、切換新锈、調(diào)度及應(yīng)用程序的管理和調(diào)度等工作) binder->
Lanuch:也是應(yīng)用,也是一個acitivity
instrumentation:execStartActivity()
activitymanager:產(chǎn)生與IActivityManger, 這個是寫在aidl文件中的類,
activitymangerservice(ams):ActivityManagerService(AMS)負(fù)責(zé)系統(tǒng)中四大組件的啟動兆览、切換、調(diào)度及應(yīng)用程序的管理和調(diào)度等工作,是服務(wù)端進程:中間通過binder機制塞关,Aidl文件抬探。進行顯示還是隱式跳轉(zhuǎn)的判斷
ActivityStackSupervisor:中進行一列的處理,獲取當(dāng)前activity的啟動模式帆赢,當(dāng)前intent是隱式還是顯示小压,暫停正在啟動的頁面砰左,以及啟動activity的進程,啟動前判斷當(dāng)前應(yīng)用的進程是否啟動场航,如果沒有啟動通知ActivityMangerService
Process:打開用來與Zygote進程通信的Socket缠导,
ActivityThread:穿件新進程的時候,執(zhí)行activityThread的main方法溉痢,然后attach到AMS僻造,并將新進程的ApplicationThread對象傳給AMS.
ActivityManagerService:調(diào)用ActivityStackSuperVisor來在新的進程中啟動Activity
ActivityStackSuperVisor:通過applicationThread 啟動acitivity
ApplicationThread:發(fā)送message到ActivityThread中
ActivityThread:處理message,通過反射獲取到需要啟動的acivity和application
為什么Handler能夠跨線程通信孩饼?
Handler的創(chuàng)建與Looper有關(guān)髓削,我們可以在主線程中創(chuàng)建,也可以在子線程中創(chuàng)建镀娶,由于主線程中已經(jīng)創(chuàng)建好了Looper立膛,
首先主線程中會自動創(chuàng)建主線程的loopre對象在ActivityThread中
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在子線程中創(chuàng)建首先調(diào)用 Looper.prepare(),再然后 Looper.loop();具體的
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e("info","--->");
Toast.makeText(MainActivity.this,"da",Toast.LENGTH_LONG).show();
}
};
handler.sendEmptyMessage(1);
Looper.loop();
}
}).start();
現(xiàn)在分析為什么主線程創(chuàng)建的Handler,而子線程利用Handler能夠發(fā)送消息到主線程?
前面已經(jīng)說過梯码,主線程會默認(rèn)創(chuàng)建一個主線程的Looper宝泵,當(dāng)我們從子線程handler.sendEmptyMessage(1)消息的時候,知道這個過程是將msg壓入到消息隊列的過程轩娶。當(dāng)msg進入到messagequeue中儿奶,壓入到messagequeue中之前有個msg與handler的綁定關(guān)系“ msg.target = this”,其中這是就是發(fā)送當(dāng)前msg的Handler鳄抒,主線程中默認(rèn)調(diào)用了由于調(diào)用了Looper.looper()方法闯捎。將不斷輪詢其中的msg,最終調(diào)用的處理的地點是msg.target.dispatchMessage(msg);
主要看msg.target這個對象许溅,從上面可知這是發(fā)送當(dāng)前msg的Handler對象瓤鼻。在源碼中msg和Handler有個綁定的關(guān)系。誰發(fā)送的msg贤重,該msg保存發(fā)送Handler的引用茬祷,最后交由這個Handler來處理msg。
Looper中有個無限輪詢消息隊列的操作游桩,為什么沒有導(dǎo)致App沒有報ANR牲迫?
產(chǎn)生ANR的原因有2種:
- 在指定時間內(nèi)沒有響應(yīng)輸入的事件.
- 處理響應(yīng)的事件超時耐朴。
Android程序的入口就是ActivityThread 的main方法借卧,如果main方法執(zhí)行完了,那么應(yīng)用也就執(zhí)行完了筛峭,所以looper是無限循環(huán)是有必要的铐刘,不然程序會自動退出。所以在Android中其他的所有操作都是在這個無限循之內(nèi)影晓。looper.loop()理論上可能會造成堵塞镰吵,所說的堵塞是指處理事件不夠快檩禾,就不會造成ANR,Looper.loop()本身是不會堵塞的疤祭。