写在四大组件之前------androidframework框架分析简略分析和系统启动流程

} catch (Throwable ex) {

Slog.e(“System”, “******************************************”);

Slog.e(“System”, “************ Failure starting system services”, ex);

throw ex;

}

…ignore some code…

}

//初始化系统上下文对象mSystemContext,并设置默认的主题,mSystemContext实际上是一个ContextImpl对象。

调用ActivityThread.systemMain()的时候,会调用ActivityThread.attach(true),而在attach()里面,则创建了Application对象,并调用了Application.onCreate()。

private void createSystemContext() {

ActivityThread activityThread = ActivityThread.systemMain();

mSystemContext = activityThread.getSystemContext();

mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);

}

//在这里开启了几个核心的服务,因为这些服务之间相互依赖,所以都放在了这个方法里面。

private void startBootstrapServices() {

…ignore some code…

//初始化ActivityManagerService

mActivityManagerService = mSystemServiceManager.startService(

ActivityManagerService.Lifecycle.class).getService();

mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

//初始化PowerManagerService,因为其他服务需要依赖这个Service,因此需要尽快的初始化

mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

// 现在电源管理已经开启,ActivityManagerService负责电源管理功能

mActivityManagerService.initPowerManagement();

// 初始化DisplayManagerService

mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

//初始化PackageManagerService

mPackageManagerService = PackageManagerService.main(mSystemContext, mInstaller,

mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

…ignore some code…

}}

这段代码发生了太多事情,开启了n个服务,ActivityThread的创建和main()方法也在此调用。

我们的ActivityManagerService对象已经创建好了,并且完成了成员变量初始化。而且在这之前,调用createSystemContext()创建系统上下文的时候,也已经完成了mSystemContext和ActivityThread的创建。注意,这是系统进程开启时的流程,在这之后,会开启系统的Launcher程序,完成系统界面的加载与显示.

所有App共用一些系统服务,比如我们这里提到的ActivityManagerService,和前面提到的PackageManagerService、WindowManagerService等等,这些基础的系统服务是被所有的App公用的,当某个App想实现某个操作的时候,要告诉这些系统服务,比如你想打开一个App,那么我们知道了包名和MainActivity类名之后就可以打开。

Intent intent = new Intent(Intent.ACTION_MAIN);

intent.addCategory(Intent.CATEGORY_LAUNCHER);

ComponentName cn = new ComponentName(packageName, className);

intent.setComponent(cn);

startActivity(intent);

AMS来通知zygote进程来fork一个新进程,来开启我们的目标App的。

App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。

那么AMS有什么用呢?在前面我们知道了,如果想打开一个App的话,需要AMS去通知zygote进程,除此之外,其实所有的Activity的开启、暂停、关闭都需要AMS来控制,所

以我们说,AMS负责系统中所有Activity的生命周期。

在Android系统中,任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。

Launcher


本质上也是一个应用程序,和我们的App一样,也是继承自Activity.

launcher.xml

<com.android.launcher2.DragLayer

android:id=“@+id/drag_layer”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:fitsSystemWindows=“true”>

<include

android:id=“@+id/dock_divider”

layout=“@layout/workspace_divider”

android:layout_marginBottom=“@dimen/button_bar_height”

android:layout_gravity=“bottom” />

<include

android:id=“@+id/paged_view_indicator”

layout=“@layout/scroll_indicator”

android:layout_gravity=“bottom”

android:layout_marginBottom=“@dimen/button_bar_height” />

<com.android.launcher2.Workspace

android:id=“@+id/workspace”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:paddingStart=“@dimen/workspace_left_padding”

android:paddingEnd=“@dimen/workspace_right_padding”

android:paddingTop=“@dimen/workspace_top_padding”

android:paddingBottom=“@dimen/workspace_bottom_padding”

launcher:defaultScreen=“2”

launcher:cellCountX=“@integer/cell_count_x”

launcher:cellCountY=“@integer/cell_count_y”

launcher:pageSpacing=“@dimen/workspace_page_spacing”

launcher:scrollIndicatorPaddingLeft=“@dimen/workspace_divider_padding_left”

launcher:scrollIndicatorPaddingRight=“@dimen/workspace_divider_padding_right”>

</com.android.launcher2.Workspace>

…ignore some code…

</com.android.launcher2.DragLayer>

Launcher大量使用标签来实现界面的复用,而且定义了很多的自定义控件实现界面效果,dock_divider从布局的参数声明上可以猜出,是底部操作栏和上面图标

布局的分割线,而paged_view_indicator则是页面指示器,和App首次进入的引导页下面的界面引导是一样的道理。当然,我们最关心的是Workspace这个布局,因为注释里

面说在这里面包含了5个屏幕的单元格,想必你也猜到了,这个就是在首页存放我们图标的那五个界面(不同的ROM会做不同的DIY,数量不固定)。

不管我们从哪儿点图片,最后都会调用。

mLauncher.startActivitySafely(v, appInfo.intent, appInfo);而startActivitySafely内部是调用了startActivity(v, intent, tag)

再深入看源码发现,startActivity()调用的其实是startActivityForResult()这个方法。

所以,Launcher中开启一个App,其实和我们在Activity中直接startActivity()基本一样,都是调用了Activity.startActivityForResult()

@Override

public void startActivity(Intent intent, @Nullable Bundle options) {

if (options != null) {

startActivityForResult(intent, -1, options);

} else {

// Note we want to go through this call for compatibility with

// applications that may have overridden the method.

startActivityForResult(intent, -1);

}

}

Instrumentation


每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()

这个类里面的方法大多数和Application和Activity有关,是的,这个类就是完成对Application和Activity初始化和生命周期的工具类

App和AMS是通过Binder传递信息的,那么ActivityThread就是专门与AMS的外交工作的,Instrumentation在ActivityThread大量调用实现这些交互。

Binder通信是单方向的,当从ActivityManagerProxy指向ActivityManagerService

客户端:ActivityManagerProxy =>Binder驱动=> ActivityManagerService:系统服务

AMS想要通知ActivityThread做一些事情

客户端:ApplicationThread <=Binder驱动<= ApplicationThreadProxy:系统服务

在应用中通过intent启动Activity的过程

首先调用startActivity,最后都会转到startActivityForResult。然后调用Instrumentation.execStartActivity,在

execStartActivity里会调用ActivityManagerNative.getDefault().startActivity。ActivityManagerNative.getDefault()就是ActivityManagerProxy,这个是AMS在客户

端进程使用的代理类,在ActivityManagerNative.getDefault()中会通过ServiceManager.getService(“activity”)获取ActivityManagerService 提供的 Binder 接口,并

将这个binder传入ActivityManagerProxy。这样ActivityManagerProxy调用starActivity,里面就会调用了AMS的相应函数。这样就完成了从Activity到AMS的一次调用。

一个App的程序真正入口是ActivityThread.main()。

而ActivityThread.main()中,Application和oncreate创建和调用。

private void attach(boolean system) {

sCurrentActivityThread = this;

mSystemThread = system;

//普通App进这里

if (!system) {

ignore some code…

RuntimeInit.setApplicationObject(mAppThread.asBinder());

final IActivityManager mgr = ActivityManagerNative.getDefault();

try {

mgr.attachApplication(mAppThread);

} catch (RemoteException ex) {

// Ignore

}

} else {

//这个分支在SystemServer加载的时候会进入,通过调用

// private void createSystemContext() {

// ActivityThread activityThread = ActivityThread.systemMain();

//}

// public static ActivityThread systemMain() {

// if (!ActivityManager.isHighEndGfx()) {

// HardwareRenderer.disable(true);

// } else {

// HardwareRenderer.enableForegroundTrimming();

// }

// ActivityThread thread = new ActivityThread();

// thread.attach(true);

// return thread;

// }

}

}

ActivityThread


整个Android应用进程的体系非常复杂,而ActivityThread是真正的核心类,它的main方法,是整个应用进程的真正入口。

ActivityThread类的对象的关联图

在这里插入图片描述

从图中可以知道,mActivities、mServices和mProviderMap 这三个变量都被保存在ArrayMap之中,他们分别保存了应用中所有的

Activity对象、Services对象、和ContentProvider对象。

同为四大组件的BroadcastReceive去哪里了?注意,BroadcastReceiver对象没有必要用任何数据结构来保存,因为BroadcastReceiver对象的生命周期很短暂,属于我调用它时,再创建运行,因此不需要保存BroadcastReceiver的对象。

我们都知道应用中Applicaiton对象是唯一的,而mInitialApplication变量是恰恰是Application对象。当你的应用自定义一个派生Applicaiton类,则它就是mInitialApplication了。

ApplicationThread类型变量mAppThread是一个Binder实体对象,ActivityManagerService作为Client端调用ApplicationThread的接口,目的是用来调度管理Activity,这个我们未来会细说。

变量mResourcesManager管理着应用中的资源。

ActivityThread相当于一个CEO,管理调度着几乎所有的Android应用进程的资源和四大组件

ActivityThread的main方法

main方法的代码:

public static void More …main(String[] args) {

SamplingProfilerIntegration.start();

// 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());

//增加一个保存key的provider

Security.addProvider(new AndroidKeyStoreProvider());

// Make sure TrustedCertificateStore looks in the right place for CA certificates

//为应用设置当前用户的CA证书保存的位置

final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());

TrustedCertificateStore.setDefaultUserDirectory(configDir);

//设置进程的名称

Process.setArgV0(“”);

Looper.prepareMainLooper();

//创建ActivityThread 对象

ActivityThread thread = new ActivityThread();

thread.attach(false);

if (sMainThreadHandler == null) {

sMainThreadHandler = thread.getHandler();

}

if (false) {

Looper.myLooper().setMessageLogging(new

LogPrinter(Log.DEBUG, “ActivityThread”));

}

Looper.loop();

throw new RuntimeException(“Main thread loop unexpectedly exited”);

}

if (!system) {

ViewRootImpl.addFirstDrawHandler(new Runnable() {

@Override

public void More …run() {

ensureJitEnabled();

}

});

android.ddm.DdmHandleAppName.setAppName(“”,

UserHandle.myUserId());

//将mAppThread放到RuntimeInit类中的静态变量

RuntimeInit.setApplicationObject(mAppThread.asBinder());

final IActivityManager mgr = ActivityManagerNative.getDefault();

try {

//将mAppThread传入ActivityThreadManager中

mgr.attachApplication(mAppThread);

} catch (RemoteException ex) {

// Ignore

}

// Watch for getting close to heap limit.

BinderInternal.addGcWatcher(new Runnable() {

@Override public void More …run() {

if (!mSomeActivitiesChanged) {

return;

}

Runtime runtime = Runtime.getRuntime();

long dalvikMax = runtime.maxMemory();

long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();

if (dalvikUsed > ((3*dalvikMax)/4)) {

if (DEBUG_MEMORY_TRIM) Slog.d(TAG, “Dalvik max=” + (dalvikMax/1024)

  • " total=" + (runtime.totalMemory()/1024)

  • " used=" + (dalvikUsed/1024));

mSomeActivitiesChanged = false;

try {

mgr.releaseSomeActivities(mAppThread);

} catch (RemoteException e) {

}

}

}

});

}

当传入的参数为false时,就走到了如上面贴出的代码中:

此时主要完成两件事

1.调用 RuntimeInit.setApplicationObject() 方法,把对象mAppThread(Binder)放到了RuntimeInit类中的静态变量mApplicationObject中。

mAppThread的类型是ApplicationThread,它是ActivityThread的成员变量,定义和初始化如下:

final ApplicationThread mAppThread = new ApplicationThread();

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
icationThread();

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-C6WIZUsy-1715884634370)]

[外链图片转存中…(img-KplIRJLJ-1715884634371)]

[外链图片转存中…(img-FHvgNq9H-1715884634372)]

[外链图片转存中…(img-A5oLtOMz-1715884634373)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值