总览

获取applicationThread,AMS这两个Binder

attach时,将获取applicationThread对象也传递到AMS进程,请求远程调用通知AMS应用进程想要创建Application,此时AMS为服务端

AMS收到消息,请求调用applicationThread的远程接口,此时AMS为客户端

applicationThread收到AMS的请求,通过Handler发起创建Application的处理任务,后面就没有远程接口调用了

通过反射创建Application的实例,通过Instrumentation启动Application的onCreate方法

详细流程分析

从 ActivityThread.java 的main方法开始看;

public static void main(String[] args) {...ActivityThread thread = new ActivityThread();thread.attach(system=false, startSeq);//1...
}

进入attach方法;

if(!system){final IActivityManager mgr = ActivityManager.getService();try {mgr.attachApplication(mAppThread, startSeq);//1} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}
}

非系统应用流程,根据 getSeervice和捕获的RemoteException可以断定,此处在使用Binder进行远程接口调用。
转身看下mAppThread是什么?

final ApplicationThread mAppThread = new ApplicationThread();private class ApplicationThread extends IApplicationThread.Stub {//批量的schedule*接口,比如scheduleReceiver、scheduleCreateService等public final void schedule*//TODO 关键方法public final void bindApplication(some args){}//1//一堆dump方法,比如dumpMemory、dumpActivity等}

可以看到,ApplicationThread是一个实现了远程接口的Binder客户端,内部封装实现了很多远程接口。不过这个客户端什么时候连接的服务器还未可知,没有找到bindService关键字,反正此时应该已经连接上对应的Service了。应该是在RuntimeInit.java类中进行应用进程启动时启动的。
回来看下前一步服务的实例IActivityManager.attachApplication()内部的实现。

先获取AMS的实例,此处获取AMS实例代码跟Activity启动流程中一致。

public static IActivityManager getService() {return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};

获取到AMS的Binder后,继续查看ActivityManagerService.java中的attachApplication方法。

public final void attachApplication(IApplicationThread thread, long startSeq) {synchronized (this) {int callingPid = Binder.getCallingPid();final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid, callingUid, startSeq); //1Binder.restoreCallingIdentity(origId);}
}

单例获取AMS实例,AMS服务在系统启动就已经注册到ServiceManager了,此处直接去获取Binder实例就行,ServiceManager以Binder池的方式管理注册的Server。
AMS的attachApplication方法中进入到attachApplicationLocked方法。

private boolean attachApplicationLocked(@NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {try {AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);thread.asBinder().linkToDeath(adr, 0);//1app.deathRecipient = adr;} catch (RemoteException e) {app.resetPackageList(mProcessStats);mProcessList.startProcessLocked(app,new HostingRecord("link fail", processName),ZYGOTE_POLICY_FLAG_EMPTY);return false;}final ActiveInstrumentation instr2 = app.getActiveInstrumentation();if (instr2 != null) {//2thread.bindApplication(processName, appInfo, providerList,instr2.mClass,profilerInfo, instr2.mArguments,instr2.mWatcher,instr2.mUiAutomationConnection, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.isPersistent(),new Configuration(app.getWindowProcessController().getConfiguration()),app.compat, getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, autofillOptions, contentCaptureOptions,app.mDisabledCompatChanges);} else {thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,null, null, null, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.isPersistent(),new Configuration(app.getWindowProcessController().getConfiguration()),app.compat, getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, autofillOptions, contentCaptureOptions,app.mDisabledCompatChanges);}}

先给ApplicationThread这个Binder上个死亡代理,根据这个死亡代理应该可以找到对应的Service是如何重新启动的,感兴趣可以继续深入,咱们继续往下走。
此处调用到thread.bindApplication接口,前面咱们查看ApplicationThread时有看到,直接切入。

private class ApplicationThread extends IApplicationThread.Stub {//批量的schedule*接口,比如scheduleReceiver、scheduleCreateService等public final void schedule*//TODO 关键方法public final void bindApplication(some args){AppBindData data = new AppBindData();...一堆参数sendMessage(H.BIND_APPLICATION, data);//1}//一堆dump方法,比如dumpMemory、dumpActivity等}

到达咱们Android开发工程师比较熟悉的点了,封装了一堆参数后,通过H这个Handler对象发了一条BIND_APPLICATION消息,咱们看看这条消息去哪了,直接跟进BIND_APPLICATION这个消息的捕捉位置。

//消息分发
class H extends Handler{public void handleMessage(Message msg){swich(msg.what){case BIND_APPLICATION: AppBindData data = (AppBindData)msg.obj;handleBindApplication(data);//1break;...省略}}
}

进入消息分发处理方法,这个方法比较长,注意阅读能看懂的代码,不求甚解,跟踪data的处理。

private void handleBindApplication(AppBindData data) {//各种初始化,比如进程名,应用名,AsyncTask线程池的配置,时区,网络发现//Context的初始化final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);try {final ClassLoader cl = instrContext.getClassLoader();mInstrumentation = (Instrumentation)//1cl.loadClass(data.instrumentationName.getClassName()).newInstance();} catch (Exception e) {throw new RuntimeException("Unable to instantiate instrumentation "+ data.instrumentationName + ": " + e.toString(), e);}final ComponentName component = new ComponentName(ii.packageName, ii.name);mInstrumentation.init(this, instrContext, appContext, component,//1data.instrumentationWatcher, data.instrumentationUiAutomationConnection);...Application app;app = data.info.makeApplication(data.restrictedBackupMode, null);//2mInstrumentation.onCreate(data.instrumentationArgs);mInstrumentation.callApplicationOnCreate(app);//3
}

通过反射实例化mInstrumentation对象,该对象为Android系统组件的管家,目前看可以控制Application和Activity的生命周期。
创建Application对象,进去看下创建的代码

//LoadApk.java #makeApplication
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation){...app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);//1appContext.setOuterContext(app);...
}//Instrumentation.java #newApplication
public Application newApplication(ClassLoader cl, String className, Context context)throws InstantiationException, IllegalAccessException, ClassNotFoundException {Application app = getFactory(context.getPackageName()).instantiateApplication(cl, className);//2app.attach(context);//首先回调attachBaseContext方法return app;
}//AppComponentFactory #instantiateApplication
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,@NonNull String className)throws InstantiationException, IllegalAccessException, ClassNotFoundException {return (Application) cl.loadClass(className).newInstance();//3
}

可以看出最后还是通过反射初始化了Application。
最后通过mInstrumentation对象完成Application类的onCreate方法的调用。

mInstrumentation.callApplicationOnCreate(app);//1//Instrumentation.java #callApplicationOnCreate
public void callApplicationOnCreate(Application app) {app.onCreate();
}

Application的启动流程相关推荐

  1. Application启动流程

    先对整体有了一个基本的认识之后,再去看细节 谈到Android Application的启动流程,很多文章都是各种源码类和方法的一堆调用关系,这样的文章就算看一百遍,也只是云里雾里.源码得看,但是最好 ...

  2. 文化袁探索专栏——Activity|Application启动流程

    文化袁探索专栏--Activity.Window和View三者间关系 文化袁探索专栏--View三大流程#Measure 文化袁探索专栏--View三大流程#Layout 文化袁探索专栏--消息分发机 ...

  3. Activity启动流程(六)注册目标Activity进程到system_server进程以及创建目标Activity进程Application

    注册Activity应用进程到system_server以及创建Activity应用进程Application Android四大组件源码实现详解系列博客目录: Android应用进程创建流程大揭秘 ...

  4. Apk应用安全加固所需了解的Application启动流程

    本文使用Android Q(API 29)版本源代码进行讲解 很多人认为Android应用加载入口是Application的onCreate,实则不然.当点击进入应用时,Zygote进程会fork出一 ...

  5. 源码分析-Activity的启动流程

    以android 6.0源码为参考,其他版本api会稍有不同 在Activity中,启动一个Activity的方法 @Override public void startActivity(Intent ...

  6. 【拒绝一问就懵】之Activity的启动流程

    背景介绍 从事开发到了一定阶段,想要提高就必须搞明白系统的一些工作原理.为什么?因为只有明白了这些,你才能针对平台的特性写出优质的代码.当遇到棘手的问题时,你才能更快速的结合系统原理去寻找最优解决方案 ...

  7. activiti自己定义流程之整合(五):启动流程时获取自己定义表单

    流程定义部署之后,自然就是流程定义列表了,但和前一节一样的是,这里也是和之前单独的activiti没什么差别.因此也不多说.我们先看看列表页面以及相应的代码,然后在一步步说明点击启动button时怎样 ...

  8. 深入理解Activity启动流程(三)–Activity启动的详细流程2

    本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--A ...

  9. Kubelet源码分析(一):启动流程分析

    源码版本 kubernetes version: v1.3.0 简介 在Kubernetes急群众,在每个Node节点上都会启动一个kubelet服务进程.该进程用于处理Master节点下发到本节点的 ...

最新文章

  1. android IPC 进程间通讯
  2. mac下使用git的冲突的解决方案
  3. win2008r2下安装sql2008r2初版
  4. 用极大似然法估计因子载荷矩阵_第7章-因子分析.ppt
  5. JBoss 类加载器问题解决
  6. 伯克利电子和计算机工程申请入口
  7. Actuator对于JMX支持
  8. java开发学生管理系统,看这篇足矣了!
  9. SQLServer之函数简介 1
  10. BUUOJ reverse 刮开有奖
  11. 【python教程入门学习】检验Python安装成功的方法
  12. 一些值得注意的算法题——队列、栈
  13. tomcat绿色版及安装版修改内存大小的方法
  14. Directed Minimum Spanning Tree: Chu-Liu/Edmonds Algorithm
  15. java jar 启动脚本
  16. 马拦过河卒问题 (递推解法)
  17. 2030影院群站专用苹果CMS10自适应手机电影整站源码影视模板下载
  18. 易宝支付 java_易宝支付工具类
  19. The NPF driver isn't running. You may have trouble capturing or listing interfaces
  20. 局域网共享文件夹/共享文件夹无法访问解决办法

热门文章

  1. java poi导出PPT格式
  2. 计算机原理探究第一部分教案,高中信息技术《计算机结构原理初步》教案
  3. PIL读入图片转为BGR
  4. lua搭建ui_[专栏作家] Lua写UI的一些使用心得
  5. [转]谷歌企业文化建设分析
  6. 真正的程序员就应该这样.
  7. windows7 文件夹提示“您当前无权访问该文件夹”的解决方法
  8. 杂记二 · 永远不服输
  9. html图片向两边展开效果,通过CSS3 transform实现图片浏览的几种效果
  10. Xshell 6免费安装