作为一个android开发者,核心架构是必须要了解的。只有了解每个核心层的作用,才能更深入的理解和学习。本篇主要讲解Java Framework层核心代码流程。
文章目录
- 一,Android系统架构
- 1.System Apps
- 2.Java Framework
- 3.系统运行库层
- 4.硬件抽象层(Hardware Abstraction Layer)
- 5.Linux Kernel
- 二,系统启动架构
- 1.Loader层
- 2.Linux内核层
- 3.硬件抽象层 (HAL)
- 4. Android Runtime & 系统库
- 5.Framework层
- 6.App层
- 三,Java Framework详解
- 1,ActivityManager
- 2,WindowManager
- 3,PackageManager
- 4,InputManagerService
一,Android系统架构
这是官方提供的架构图,由于内核是基于Linux,只需要了解底层的一些作用就行。
1.System Apps
系统应用层,也就是应用层,不只是系统自带的应用(Dialer:拨号器,Email:邮件,Camera:相机,Calendar:日历等),还有广大的android应用层开发者开发的第三方应用:比如支付宝,微信,qq等。
2.Java Framework
android开发核心层,提供丰富的API给开发者。
- ActivityManagerService: 管理着android的四大组件;统一调度各应用进程。
- WindowManagerService: 控制窗口的显示、隐藏以及窗口的层序,大多数情况和View有关系的都要和它打交道。
- Content Providers: 可以让一个应用访问另一个应用的数据,共享他们的数据。
- 视图系统(View System): 丰富且可拓展,包括:列表(lists),网络(grids),文本框(text boxes),按钮(buttons)等等。
- Notification Manager: 可以在"状态栏中"显示自定义的提示信息。
- Package Manger: 对Android系统内的程序管理。
- Telephony Manager: 主要提供了一系列用于访问与手机通讯相关的状态和信息的方法,查询电信网络状态信息,sim卡的信息等。
- Resource Manager: 提供非代码资源的访问,如本地字符串,图形,和布局文件。
- Location Manager: 提供设备的地址位置的获取方式。很显然,GPS导航肯定能用到位置服务。
3.系统运行库层
Native C/C++ Libraries:C/C++程序库,许多核心 Android 系统组件和服务(例如 ART 和 HAL)构建自原生代码,需要以 C 和 C++ 编写的原生库。Android 平台提供 Java 框架 API 以向应用显示其中部分原生库的功能。例如,您可以通过 Android 框架的 Java OpenGL API 访问 OpenGL ES,以支持在应用中绘制和操作 2D 和 3D 图形。
如果开发的是需要 C 或 C++ 代码的应用,可以使用 Android NDK 直接从原生代码访问某些原生平台库。也可以利用一些.a静态库和.so动态库,NdK和Jni的开发,C和C++平台的代码移植等都需要动这层代码,编译。
Android Runtime:运行时库 , Dalvik虚拟机是Google等厂商合作开发的Android移动设备平台的核心组成部分之一。它可以支持已转换为.dex(即Dalvik Executable)格式的Java应用程序的运行,.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。(dx 是一套工具,可以将 Java .class 转换成 .dex 格式. 一个dex档通常会有多个.class。由于dex有时必须进行最佳化,会使档案大小增加1-4倍,以ODEX结尾。)然而Dalvik VM 效率并不是最高的。从 Android 4.4 开始,Google 开发者引进了新的 Android 运行环境 ART(意思就是 Android Runtime。Android 官方页面的介绍中,也将其称作新的虚拟机),以替代旧的 Dalvik VM。Android 5.0之后就彻底的代替了。ART 的机制与 Dalvik 不同。在Dalvik下,应用每次运行的时候,字节码都需要通过即时编译器转换为机器码,这会拖慢应用的运行效率,而在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译(AOT,Ahead-Of-Time)。这样的话,应用的启动(首次)和执行都会变得更加快速。代价就是安装会慢。里面有 预先 (AOT) 和即时 (JIT) 编译,优化的垃圾回收 (GC),更好的调试支持,包括专用采样分析器、详细的诊断异常和崩溃报告,并且能够设置监视点以监控特定字段,Android Runtime Excepiton 就出自这里。
4.硬件抽象层(Hardware Abstraction Layer)
硬件抽象层 (HAL) 提供标准界面,向更高级别的 Java API 框架显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如:Audio音频模块,BlueTooth:蓝牙模块,Camera:相机模块,Sensors:传感器。系统内置对传感器的支持达13种,他们分别是:加速度传感器(accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块。厂商会在这层定义自己的HAL接口。
5.Linux Kernel
Android依赖于Linux2.6内核提高的高核心系统服务,例如安全,内存管理,进程管理,网络斎等等方面内容。内核作为一个抽象层,存在与硬件层和软件层之间。android对Linux下面内容做了增强。有下面这些驱动(Audio,IPC,Display,BlueTooth,Camera,USB)。
最后形成思维导图方便记忆
二,系统启动架构
Android系统启动过程由上图从下往上的一个过程,Boot Loader -> Kernel -> Native -> Framework -> App。
1.Loader层
Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设代码开始执行,然后加载引导程序到RAM;Boot Loader:这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数等功能。
2.Linux内核层
启动Kernel的swapper进程(pid=0):该进程又称为idle进程,系统初始化过程Kernel由无到有开创的第一个进程,,用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖。
3.硬件抽象层 (HAL)
硬件抽象层 (HAL) 提供标准接口,HAL包含多个库模块,其中每个模块都为特定类型的硬件组件实现一组接口,比如WIFI/蓝牙模块,当框架API请求访问设备硬件时,Android系统将为该硬件加载相应的库模块。
4. Android Runtime & 系统库
每个应用都在其自己的进程中运行,都有自己的虚拟机实例。ART通过执行DEX文件可在设备运行多个虚拟机,DEX文件是一种专为Android设计的字节码格式文件,经过优化,使用内存很少。
ART主要功能包括:预先(AOT)和即时(JIT)编译,优化的垃圾回收(GC),以及调试相关的支持。
这里的Native系统库主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖。
init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程;init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务;init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。
5.Framework层
Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:加载ZygoteInit类,注册Zygote Socket服务端套接字,加载虚拟机,提前加载类preloadClasses,提前加载资源preloadResouces。
System Server进程,是由Zygote进程fork而来的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务。 Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务。
6.App层
Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App;Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。所有的App进程都是由Zygote进程fork生成的。
三,Java Framework详解
不管是做系统开发,还是应用开发Framework都需要有所了解。虽然应用开发不涉及Framework层的定制和修改,但原理也要知道,知其然也要知其所以然。
1,ActivityManager
ActivityManager是对Activity管理、运行时功能管理和运行时数据结构的封装,进程(Process)、应用程序/包、服务(Service)、任务(Task)信息等。
但是这些信息真正维护并不是ActivityManager来负责的,从其中的众多接口getXXX()可以看到其中都是使用:ActivityManagerNative.getDefault()的操作来实现这些信息的获取。
- ActivityManager.MemoryInfo: 系统可用内存信息。
- ActivityManager.RecentTaskInfo: 最近的任务信息。
- ActivityManager.RunningAppProcessInfo: 正在运行的进程信息。
- ActivityManager.RunningServiceInfo: 正在运行的服务信息。
- ActivityManager.RunningTaskInfo: 正在运行的任务信息。
类图如下:
IActivityManager作为ActivityManagerProxy和ActivityManagerNative的公共接口,所以两个类具有部分相同的接口,可以实现合理的代理模式;ActivityManagerProxy代理类是ActivityManagerNative的内部类;ActivityManagerNative是个抽象类,真正发挥作用的是它的子类ActivityManagerService。
ActivityManager在应用进程中,所有的Manager都在应用进程,而ActivityManagerService运行在系统进程中(system_server)。
ActivityManager通过代理ActivityManagerProxy实现与ActivityManagerService通信,流程如下:
@Deprecated
public List<RunningServiceInfo> getRunningServices(int maxNum)
throws SecurityException {
try {
return getService()
.getServices(maxNum, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
从上边源码中可以看出,ServiceManager.getService(“activity”),获取系统的“activity”的Service,所有的Service都是注册到ServiceManager进行统一管理。这样就创建了一个对ActivityManagerService实例的本地代理对象ActivityManagerProxy实例。
ActivityManagerService
AMS负责管理着android的四大组件;统一调度各应用进程。
AMS在SystemServer中启动
private void run(){
......
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
......
}
private void startBootstrapServices() {
Installer installer = mSystemServiceManager.startService(Installer.class);
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mActivityManagerService.setSystemProcess();
}
mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class)这个方法主要是创建ActivityManagerService.Lifecycle对象并调用Lifecycle.onStart方法
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
//真正创建AMS
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
mService.start();
}
public ActivityManagerService getService() {
return mService;
}
}
AMS创建了三个线程
public ActivityManagerService(Context systemContext) {
mContext = systemContext;
mFactoryTest = FactoryTest.getMode();
mSystemThread = ActivityThread.currentActivityThread();
//创建一个前台线程并获取mHandler
mHandlerThread = new ServiceThread(TAG,
android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
//创建一个UI线程,这个线程主要处理跟ams内部发出的需要进行ui处理的事件
mUiHandler = new UiHandler();
......
}
当调用startActivityForResult
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
......
}
}
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
if (options == null) {
options = ActivityOptions.makeBasic().toBundle();
}
result = am.onStartActivity(who, intent, options);
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
//通过Binder通信最终在AMS中执行
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
//检查activity是否启动
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
在AMS中的调用
/**
* @deprecated use {@link #startActivityWithFeature} instead
*/
@Deprecated
@Override
public int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return mActivityTaskManager.startActivity(caller, callingPackage, null, intent,
resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions);
}
在ActivityTaskManager调用
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
2,WindowManager
android的窗口分为三种:
- 应用程序窗口 (Application Window): 包括所有应用程序自己创建的窗口,以及在应用起来之前系统负责显示的窗口。
- 子窗口(Sub Window):比如应用自定义的对话框,或者输入法窗口,子窗口必须依附于某个应用窗口(设置相同的token)。
- 系统窗口(System Window): 系统设计的,不依附于任何应用的窗口,比如说,状态栏(Status Bar),
导航栏(Navigation Bar), 壁纸(Wallpaper), 来电显示窗口(Phone),锁屏窗口(KeyGuard),
信息提示窗口(Toast), 音量调整窗口,鼠标光标等等。
核心实现类是WindowManagerImpl
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
mGlobal是WindowManagerGlobal:
public final class WindowManagerImpl implements WindowManager {
@UnsupportedAppUsage
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
...
}
WindowManager操作Window,不过具体的实现细节还是WindowManagerGlobal这个类来做的,这个类是一个单例模式。
继续看下WindowManagerGlobal.java的addView函数:
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
……
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
if (parentWindow != null) {
// 界面布局的限制
parentWindow.adjustLayoutParamsForSubWindow(wparams);
} else {
final Context context = view.getContext();
if (context != null
&& (context.getApplicationInfo().flags
& ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
}
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
……
// 构建界面控制
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
//将View显示到手机窗口
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}
其中创建了ViewRootImpl
ViewRootImpl 是一个视图层次结构的顶部,ViewRootImpl 实现了 View 与 WindowManager 之间所需要的协议,作为 WindowManagerGlobal 中大部分的内部实现。
在 WindowManagerGlobal 中实现方法中,都可以见到 ViewRootImpl,也就说 WindowManagerGlobal 方法最后还是调用到了 ViewRootImpl。
比如addView,removeView,update 的调用顺序:WindowManagerImpl -> WindowManagerGlobal -> ViewRootImpl。
而且WindowManager.java 是继承的ViewManager。
WindowManagerService
3,PackageManager
4,InputManagerService
InputManagerService是事件输入的关键组件,在system_process进程中。通过socket通信与客户端进行交互。
Linux内核: 接受输入设备的中断,并将原始事件的数据写入设备节点中设备接电,作为内核与 IMS 的桥梁,将原始事 件的数据暴露给用户空间,以便 IMS 可以从中读取事件;
InputManagerService: 一个 Android 系统服务,分为 Java 层和 Native 层两部分,Java 层负责与 WMS 通信,而 Native 层则是 InputReader 和 InputDispatcher 两个输入系统关键组件的运行容器;
EventHub: 直接访问所有的设备节点,通过一个名为 getEvents() 的函数将所有输入系统相关的待处理的底层事件返回给使用者,包括原始输入事件,设备节点的增删等;
InputReader: IMS 中的关键组件之一,它运行在一个独立的线程中,负责管理输入设备的列表和配置,以及进行输入事件的加工处理,它通过其线程循环不断地通过 getEvents() 函数从 EventHub 中将事件取出并进行处理,对于设备节点的增删事件,它会更新输入设备列表与配置;对于原始输入事件,InputReader对其进行翻译,组装,封装为包含更多信息,更多可读性的输入事件,然后交给InputDispatcher进行派发;
InputReaderPolicy: 为 InputReader 的事件加工处理提供一些策略配置
InputDispatcher: 是 IMS 中的另一个关键组件,运行于一个独立的线程中,InputDispatcher 中保管来自 WMS 的所有窗口的信息,收到 InputReader 的输入事件后,会在其保管的窗口中寻找合适的窗口,并将事件派发给此窗口;
InputDispatcherPolicy: 为 InputDispatcher 的派发过程提供策略控制,例如 HOME 键被 InputDispatcherPolicy 截取到 PhoneWindowManager 中处理,并阻止窗口收到 HOME 键按下的事件;
WindowManagerService: 它并不是输入系统的一员,新建窗口时,WMS 为新窗口和 IMS 创建了事件传递所用的通道,会将窗口的可点击区域,焦点窗口等信息实时更新到 IMS 的 InputDispatcher 中,使得 InputDispatcher 可以正确将事件派发到指定窗口;
ViewRootImpl: 对某些窗口,如壁纸窗口,SurfaceView 的窗口来说,窗口就是输入事件派发的终点,而对其他的如Activity,对话框等使用了 Android 控件系统的窗口来说,输入事件的终点是控件。
点击屏幕执行过程
InputManagerService的Read线程捕获事件,预处理后发送给Dispatcher线程
Dispatcher找到目标窗口
通过Socket将事件发送到目标窗口
APP端被唤醒
找到目标窗口处理事件
为什么InputManagerService和APP通信使用Socket而不是Binder
- Binder本身是CS结构的,经常用于SystemServer 中不同的Service间通信,或则是由App作为Client调用Service
(如AMS)的情况,整体的方式很像是Http,即一个请求对应一个响应。而Input子系统的事件传递机制和CS架构的调用逻辑完全不一样,它是由底层出发,由Service发起像Client进行通知的,而且会有连续的多个事件以及要分发到多个App,整体和“请求-响应”结构完全不一致,用Binder实现逻辑较为复杂。 - Input系统的事件分发需要双向通信,Server -> App分发,App-> Server通知分发结果,而Binder做双向通信也不太方便。
- 尽管Binder性能较为优秀,不过它的性能优势主要在于数据传递少一次Copy,而在Input系统中所传递的都是一些事件,事件本身的数据量都是比较小的,所以这个内存Copy的性能优势本身也不太明显。