Android Framework:
- Android Framework学习(一)系统服务相关
- Android Framework学习(二)应用进程启动相关
- Android Framework学习(三)Activity相关
Android Framework涉及到linux相关,本文也只是冰山一角,但是虽不能窥其全貌,了解其具体流程还是有点必要的。
Zygote启动
我们知道Android的所有进程都是通过Zygote进程孵化而来的,那就有个疑问Zygote又是哪来的?
所有,我们首先来了解一下Zygote进程是怎么启动的。
首先Linux系统启动后会在用户空间创建第一个进程init进程,进程号固定为1。然后调用init中的main()方法执行init进程的职责。对于init进程的功能分为4部分:
- 解析并运行所有的init.rc相关文件
- 根据rc文件,生成相应的设备驱动节点
- 处理子进程的终止(signal方式)
- 提供属性服务的功能
在这里便通过fork和execve系统调用启动了Zygote进程.
Zygote启动之后,会先进入native层。启动Android的虚拟机–>注册Android的JNI函数–>再进入Java层。
来到java层后。主要是做一下事情
- 预加载资源:便于后面孵化子进程时能够方便继承,预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高app启动效率
- System_server:也就是系统服务了,要注意这一点,是由zygote进程fork而来的。
- Socket Loop循坏:用来处理socket通信相关的,当接收到请求创建新进程请求时立即唤醒并执行相应工作。
这里要注意一个问题:
Zygote进程fork子进程的需要单线程环境,因为fork的时候会继承父进程的资源,如果父进程时多线程环境的话,容易出现死锁及线程间同步问题,所有fork时会切换到单线程环境。
同时这也解决了一个疑问,Zygote的IPC为什么没有采用Binder机制,按道理说Binder机制很明显要优于Socket通信,但是也就是因为Binder通信是多线程环境这个原因,故而采用了socket。
系统服务启动
下面来具体深入到代码来看SystemServer是如何启动的。
这里只截取部分,不追究细节,不然看的云里雾里毫无头绪。注意在SDK28中变为了forkSystemServer方法
ZygoteInit.java
//准备参数用于启动SystemServer
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
/* Hardcoded command line to start the system server */
String args[] = {
...
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
/* Request to fork the system server process */
//请求创建SystemServer进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
//执行SystemServer进程内方法解析启动参数
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
//完成剩余的启动工作
return handleSystemServerProcess(parsedArgs);
}
return null;
下面来看SystemServer启动
SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
//创建消息循坏
Looper.prepareMainLooper();
// Initialize native services.
System.loadLibrary("android_servers");
// Initialize the system context.
createSystemContext();
// Start services.
try {
traceBeginAndSlog("StartServices");
//可见系统服务分为以下三类
startBootstrapServices();// 启动引导服务
startCoreServices(); // 启动核心服务
startOtherServices(); // 启动其他服务
SystemServerInitThreadPool.shutdown();
}
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
SystemServer有很多,那它的启动流程是什么样的?
其主线也是按照上面的启动顺序,先启动引导服务:AMS、PMS等;再启动核心服务BatteryService、UsageStatsService、WebViewUpdateService等;最好启动其他的非必需服务:闹钟服务什么的啊
具体流程可参考Gityuna大神的文章Android系统启动-SystemServer下篇
好了,了解了系统服务的启动后,首先肯定最先看到的是桌面应用,所有来看下桌面的启动。
桌面的启动是再AMS启动后开始启动的,能再AMS中的systemReady()方法中看到调用了startHomeActivityLocked()方法
ActivityManagerService.java
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
//这里是获取Home的MainActivity的Categary
Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
//下面是获取启动所需的参数,比如桌面上需要显示的App信息
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
// For ANR debugging to verify if the user activity is the one that actually
// launched.
final String myReason = reason + ":" + userId + ":" + resolvedUserId;
//这里启动Home的Activity
mActivityStartController.startHomeActivity(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
添加自定义系统服务
我们知道,当客户端想要访问系统服务时,会通过ServerManager来查找系统服务,如果找到则返回对应的Binder,然后客户端可通过该Binder与Servive建立通信。总体的过程如下:
再来要了解系统服务的使用流程,首先通过context的getSystemService方法获取系统服务,Context的实现类为ContextImpl
ContextImpl.java
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry.java
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;//getService主要是从Context获取服务,如果未获取到则创建
}
先以BatterService为例,
BatteryStatsService.java
public static IBatteryStats getService() {
if (sService != null) {
return sService;
}
//这里也就是获取到对应的IBinder对象
IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
sService = asInterface(b);
return sService;
}
这里类似于AIDL一样,ServiceManager里面都是空实现,具体的AIDL绑定在ServiceManagerNative中
ServiceManagerNative.java
class ServiceManagerProxy implements IServiceManager {
//只截取部分
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
//熟悉的AIDL自动生成的方法,返回对应的IBinder
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
这也也就从ServerManager中获取到了系统服务。具体的添加服务也同上面一样,使用addService()方法,可能这里说的不是很深入,因为涉及到了native层,要深入的话需要大篇幅的描述,因此这里就只说明其功能。
系统服务与应用Binder服务的区别
系统服务的启动:在前面的SystemServer中也看到过,通过run方法来启动,来完成服务的初始化。也看的出是主动注册服务的。
try {
traceBeginAndSlog("StartServices");
//可见系统服务分为以下三类
startBootstrapServices();// 启动引导服务
startCoreServices(); // 启动核心服务
startOtherServices(); // 启动其他服务
SystemServerInitThreadPool.shutdown();
}
系统服务的具体调用的过程则如下所示,
应用服务的启动:
通过startService–>ContextImpl中的startServiceCommon()方法中,服务间通信建立、管理、调度的过程是交给AMS。具体的创建还是需要交给应用端完成的,完成实例创建,生命周期回调等。
应用服务的调用过程:
应用服务则不是主动注册的,而是发起bindService请求后,由AMS自己去寻找服务请求binder。被动注册。
两者的使用方式上,我个人决定在大体上区别不大,都是属于Binder范畴中,
系统服务使用是通过ServiceManager直接获取到该服务的binder对象,利用了Binder连接池,然后再利用binder对象得到暴露的接口。
应用服务则是通过Service端传入的IBinder对象获取暴露的接口。