1. activity的启动流程?
lanuch ->actvitymange->activitymagerservice(ActivityManagerService(AMS)负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作) binder->
Lanuch:也是应用,也是一个acitivity
instrumentation:execStartActivity()
activitymanager:产生与IActivityManger, 这个是写在aidl文件中的类,
activitymangerservice(ams):ActivityManagerService(AMS)负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作,是服务端进程:中间通过binder机制,Aidl文件。进行显示还是隐式跳转的判断
ActivityStackSupervisor:中进行一列的处理,获取当前activity的启动模式,当前intent是隐式还是显示,暂停正在启动的页面,以及启动activity的进程,启动前判断当前应用的进程是否启动,如果没有启动通知ActivityMangerService
Process:打开用来与Zygote进程通信的Socket,
ActivityThread:穿件新进程的时候,执行activityThread的main方法,然后attach到AMS,并将新进程的ApplicationThread对象传给AMS.
ActivityManagerService:调用ActivityStackSuperVisor来在新的进程中启动Activity
ActivityStackSuperVisor:通过applicationThread 启动acitivity
ApplicationThread:发送message到ActivityThread中
ActivityThread:处理message,通过反射获取到需要启动的acivity和application
为什么Handler能够跨线程通信?
Handler的创建与Looper有关,我们可以在主线程中创建,也可以在子线程中创建,由于主线程中已经创建好了Looper,
首先主线程中会自动创建主线程的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");
}
在子线程中创建首先调用 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();
现在分析为什么主线程创建的Handler,而子线程利用Handler能够发送消息到主线程?
前面已经说过,主线程会默认创建一个主线程的Looper,当我们从子线程handler.sendEmptyMessage(1)消息的时候,知道这个过程是将msg压入到消息队列的过程。当msg进入到messagequeue中,压入到messagequeue中之前有个msg与handler的绑定关系“ msg.target = this”,其中这是就是发送当前msg的Handler,主线程中默认调用了由于调用了Looper.looper()方法。将不断轮询其中的msg,最终调用的处理的地点是msg.target.dispatchMessage(msg);
主要看msg.target这个对象,从上面可知这是发送当前msg的Handler对象。在源码中msg和Handler有个绑定的关系。谁发送的msg,该msg保存发送Handler的引用,最后交由这个Handler来处理msg。
Looper中有个无限轮询消息队列的操作,为什么没有导致App没有报ANR?
产生ANR的原因有2种:
- 在指定时间内没有响应输入的事件.
- 处理响应的事件超时。
Android程序的入口就是ActivityThread 的main方法,如果main方法执行完了,那么应用也就执行完了,所以looper是无限循环是有必要的,不然程序会自动退出。所以在Android中其他的所有操作都是在这个无限循之内。looper.loop()理论上可能会造成堵塞,所说的堵塞是指处理事件不够快,就不会造成ANR,Looper.loop()本身是不会堵塞的。
网友评论