当前位置: 首页 > news >正文

平谷做网站360指数查询工具

平谷做网站,360指数查询工具,网站建设的基本规范有什么,网站建设心得一个Android应用是如何被启动的 前言总结1. 启动Application1.1 拉起一个新的进程1.2 启动Application1.3 AMS阶段1.4 创建Instrumentation和Application 2. 启动Activity2.1 回到AMS,启动第一个Activity 参考资料 前言 基于源码API 28,30以后的版本启动…

一个Android应用是如何被启动的

  • 前言
  • 总结
  • 1. 启动Application
    • 1.1 拉起一个新的进程
    • 1.2 启动Application
    • 1.3 AMS阶段
    • 1.4 创建Instrumentation和Application
  • 2. 启动Activity
    • 2.1 回到AMS,启动第一个Activity
  • 参考资料

前言

基于源码API 28,30以后的版本启动第一个Activity的逻辑不一样

我会只拿出我们需要关注的代码部分,因为源码太多全都看看不过来的。所以每次截代码都有省略
前言
源码只截取需要看的部分,其他部分会省略。

源码基于API 28也就是Android9.0,也就是源码还有ActivityStackSupervisor的这个版本
其他版本代码不太一样没有ActivityStackSupervisor,但是原理是相同的。

AOSP的源码在这个网站上看:http://aospxref.com/

总结

用流程总结app启动:

  1. 用户点击应用图标(或者其他方式打开app)
  2. 要打开app的进程(可能是桌面进程可能是别的Intent)通知zygote进程fork出一个新的进程用于承载app。
  3. ActivityThread通过main方法启动,通过跨进程通信,通知SystemServer进程
  4. SystemServer的AMS去找PMS拿对应的进程信息。
  5. AMS将进程信息PackageInfo返还给应用进程
  6. ActivityThread创建Instrumentation和通过反射的方式创建Application,
  7. Instrumentation调用application的生命周期。

用流程总结第一个Activity启动:

  1. AMS遍历mPackages里面的Activity标签之后,找到启动时所需要的那个Activity(根据Intent里面的那个启动标签)。
  2. 准备一个事务(clientTransaction),里面包括了Activity的启动(Callback)和拉到前台(lifecycleState)两件事。

后面的流程参考上一篇文章的第六节,我们只需要知道一旦往ActivityThread发了一个ClientTransaction之后,后面的流程就完全是固定的。

AMS(ActivityManagerService)源码解析,Activity是如何被打开的
https://blog.csdn.net/qq_41872247/article/details/125031721

1. 启动Application

1.1 拉起一个新的进程

首先我们需要明确一点的是,启动一个app,他的起点来自于桌面进程,桌面进程在用户点击app图标准备拉起app的时候,就会让Zygote进程去即使的fork一个新的app进程出来,然后寻找到这个新的app的ActivityThread类的Main方法进行执行。

这部分见https://blog.csdn.net/qq_41872247/article/details/125211491

1.2 启动Application

接下来我们就来到了ActivityThread的Main方法

public final class ActivityThread extends ClientTransactionHandlerimplements ActivityThreadInternal {private ApplicationThread mAppThread// 启动类public static void main(String[] args) {ActivityThread thread = new ActivityThread();thread.attach(false, startSeq);}private void attach(boolean system, long startSeq) {if(!system) {final IActivityManager mgr = ActivityManager.getService();try {mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}}private class ApplicationThread extend IApplicationThread.Stub {}
}

到attach,我们就通过跨进程进行binder通信了,拿到了AMS对象。我们传的对象ApplicationThread就是ActivityThread的一个内部类,持有外部引用,这个类就是负责和AMS通信。

1.3 AMS阶段

public class ActivityManagerService extends IActivityManager.Stubimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {public final void attachApplication(IApplicationThread thread, long startSeq) {synchronized (this) {attachApplicationLocked(thread, callingPid, callingUid, startSeq);}}private boolean attachApplicationLocked(@NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {ProcessRecord app;// 这段代码从PMS中请求App的数据if (app == null && startSeq > 0) {final ProcessRecord pending = mPendingStarts.get(startSeq);if (pending != null && pending.startUid == callingUid && pending.startSeq == startSeq&& handleProcessStartedLocked(pending, pid, pending.usingWrapper,startSeq, true)) {app = pending;}}if (app.isolatedEntryPoint != null) {thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);} else if (app.instr != null) {// 走这里thread.bindApplication(processName, appInfo, providers,app.instr.mClass,profilerInfo, app.instr.mArguments,app.instr.mWatcher,app.instr.mUiAutomationConnection, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.persistent,new Configuration(getGlobalConfiguration()), app.compat,getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, isAutofillCompatEnabled);} else {thread.bindApplication(processName, appInfo, providers, null, profilerInfo,null, null, null, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.persistent,new Configuration(getGlobalConfiguration()), app.compat,getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, isAutofillCompatEnabled);}}
}

AMS这部分先去PMS里面拿到当前app的相关数据(之前写在AndroidManifest里面的解析后存在mPackages的内容),
然后再返回来给ApplicationThread(走到thread.bindApplication)。

1.4 创建Instrumentation和Application

public final class ActivityThread extends ClientTransactionHandlerimplements ActivityThreadInternal {private class ApplicationThread extend IApplicationThread.Stub {public final void bindApplication(很多入参) {AppBindData data = new AppBindData();// ....将App的数据都放进data里面sendMessage(H.BIND_APPLICATION, data);}}
}

这里第一次sendMsg了,就是handler的那套流程,最后走到的是外侧的一个bindApplication方法

public final class ActivityThread extends ClientTransactionHandlerimplements ActivityThreadInternal {private static class AndroidOs extends ForwardingOs {private void handleBindApplication(AppBindData data) {// 一般都是走上面if (ii != null) {initInstrumentation(ii, data, appContext);} else {mInstrumentation = new Instrumentation();mInstrumentation.basicInit(this);}//.....省略无关代码Application app;try {// 创建appllicationapp = data.info.makeApplicationInner(data.restrictedBackupMode, null);//......// Instrumentation自己的onCreate方法,等于自己的生命周期,忽视它mInstrumentation.onCreate(data.instrumentationArgs);//......mInstrumentation.callApplicationOnCreate(app);}}private void initInstrumentation(InstrumentationInfo ii, AppBindData data, ContextImpl appContext) {try {final ClassLoader cl = instrContext.getClassLoader();mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();}//init只是把一大堆东西给他赋值到成员变量里面mInstrumentation.init(this, instrContext, appContext, component,data.instrumentationWatcher, data.instrumentationUiAutomationConnection);}}
}

他在这段代码中做了几件事:

  1. 创建Instrumentation对象
  2. 创建Application对象
  3. 调用Application的生命周期

Instrumentation的创建过程上面已经有了,接下来看makeApplicationInner是如何创建Application的:

public final class LoadedApk {private Application makeApplicationInner(boolean forceDefaultAppClass,Instrumentation instrumentation, boolean allowDuplicateInstances) {Application app = null;app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);return app;}
}public class Instrumentation {public Application newApplication(ClassLoader cl, String className, Context context)throws InstantiationException, IllegalAccessException, ClassNotFoundException {// getFactory我们具体就不看了,最终就是返回一个AppComponentFactory的对象Application app = getFactory(context.getPackageName()).instantiateApplication(cl, className);app.attach(context); //这个attach,就是我们自己定义的Application类的生命周期的那个attach,由Instrumentation直接调用return app;}
}public class AppComponentFactory {public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,@NonNull String className)throws InstantiationException, IllegalAccessException, ClassNotFoundException {// 走到最后还是反射创建的对象。return (Application) cl.loadClass(className).newInstance();}
}

虽然中间跨了很多个类,但是还是可以看得出来根本的那行代码还是反射创建Application对象。

最后看看Application的生命周期是如何被Instrumentation调用的

public class Instrumentation {public void callApplicationOnCreate(Application app) {app.onCreate();}
}

结果就是直接调用,没有任何转折。

2. 启动Activity

2.1 回到AMS,启动第一个Activity

  1. 代码回到AMS,刚刚AMS的代码还未执行完。
public class ActivityManagerService extends IActivityManager.Stubimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {private boolean attachApplicationLocked(@NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {//.. bind之后发生的事// See if the top visible activity is waiting to run in this process...// 查看在这个进程中顶部的Activity是否正在等待运行...   其实就是启动顶部Activity了if (normalMode) {try {if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}}
}public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,RecentTasks.Callbacks {boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {final String processName = app.processName;boolean didSomething = false;for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {final ActivityStack stack = display.getChildAt(stackNdx);if (!isFocusedStack(stack)) {continue;}stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);final ActivityRecord top = stack.topRunningActivityLocked();final int size = mTmpActivityList.size();for (int i = 0; i < size; i++) {final ActivityRecord activity = mTmpActivityList.get(i);if (activity.app == null && app.uid == activity.info.applicationInfo.uid&& processName.equals(activity.processName)) {try {// 通过好几层的for循环遍历app里面所有的Activity,去寻找并启动app的启动页if (realStartActivityLocked(activity, app,top == activity /* andResume */, true /* checkConfig */)) {didSomething = true;}} catch (RemoteException e) {throw e;}}}}}if (!didSomething) {ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);}return didSomething;}final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {try {// 准备启动Activity的事务final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,r.appToken);// 这里准备了一个LaunchActivityItem作为Callback,记住他,后面会用到clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),System.identityHashCode(r), r.info,mergedConfiguration.getGlobalConfiguration(),mergedConfiguration.getOverrideConfiguration(), r.compat,r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,r.persistentState, results, newIntents, mService.isNextTransitionForward(),profilerInfo));final ActivityLifecycleItem lifecycleItem;if (andResume) {// 这里我们是启动Activity,所以走resumelifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());} else {lifecycleItem = PauseActivityItem.obtain();}// 这里准备了一个ResumeActivityItem作为LifecycleState,记住他,后面会用到clientTransaction.setLifecycleStateRequest(lifecycleItem);// 发送这个事务mService.getLifecycleManager().scheduleTransaction(clientTransaction);}}
}

AMS遍历了一下启动进程的所有Activity,找到启动时要用的那个,走到了realStartActivityLocked准备启动。

后面的流程参考这篇文章的第六节,是完全一样的
AMS(ActivityManagerService)源码解析,Activity是如何被打开的
https://blog.csdn.net/qq_41872247/article/details/125031721

参考资料

码牛学院VIP课程 VIP12-2021.12.03-這染机制-01 Activity. View. WMS的协调kerwin

AOSP的源码网站:http://aospxref.com/

http://www.ds6.com.cn/news/2328.html

相关文章:

  • php除了做网站还能做什么网络软文发布
  • 顺的网站建设教程网站推广与优化平台
  • 杭州门户网站有哪些广告投放运营主要做什么
  • 网页制作素材库属不属于信息管理网站seo排名优化工具
  • 文山网站建设求职简历江门网站定制多少钱
  • 医院网站建设方案ppt绍兴百度seo排名
  • 厦门 网站建设今天今日新闻头条最新消息
  • 投资20万做网站好吗广东: 确保科学精准高效推进疫情
  • 东莞网站建设销售前景怎么样百度移动端关键词优化
  • wordpress双导航栏seo研究中心怎么了
  • 怎么做产品网站毛戈平化妆培训学校官网
  • 壁画网站建设站内seo优化
  • 店铺推广和网站优化一起做全网营销推广靠谱吗
  • 有没有帮忙做问卷调查的网站搜索引擎推广有哪些
  • 360建筑网官网下载网站seo具体怎么做
  • 珠海疫情最新消息今天又封了企业专业搜索引擎优化
  • 哪些网站是单页面应用程序国外免费域名申请
  • 如何建立网站视频seo的中文含义
  • wordpress 根目录是seo的排名机制
  • 网站做不好一直不交付怎么办网站建设案例
  • 自己怎么做优惠券网站上海网站排名优化公司
  • gomarket wordpress上海网站优化公司
  • 网站建设免费软件有哪些外贸营销系统
  • 做的好的响应式网站小程序定制开发公司
  • 教学网站开发论文seo优化师
  • 东莞市官网网站建设公司免费建站网站一站式
  • 没有网站 淘宝客广州高端网站建设公司
  • 做游戏的php网站淘宝运营培训班去哪里学
  • 网站目录文件词语搜索排行
  • 黄冈市网站建设可以免费打开网站的软件