本文简要记录下学习Android系统启动的一些细节,方便自己记忆和宏观的认识。
分析的源码是8.1.0
启动电源 => 拉起引导程序 => linux内核启动 => init进程启动 => zygote进程 => systemServer进程
//system/core/init/init.cpp
int main(int argc, char** argv) {
...
add_environment("PATH", _PATH_DEFPATH);
bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
if (is_first_stage) {
boot_clock::time_point start_time = boot_clock::now();
// Clear the umask.
umask(0);
// 挂载文件
// Get the basic filesystem setup we need put together in the initramdisk
// on / and then we'll let the rc file figure out the rest.
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
....
InitKernelLogging(argv);
....
}
...
// 属性服务初始化
property_init();
....
// 启动属性服务
start_property_service();
...
// 默认为true
if (bootscript.empty()) {
// 解析init.rc文件
parser.ParseConfig("/init.rc");
parser.set_is_system_etc_init_loaded(
parser.ParseConfig("/system/etc/init"));
parser.set_is_vendor_etc_init_loaded(
parser.ParseConfig("/vendor/etc/init"));
...
return 0;
}
可以理解为记录用户以及软件使用信息的注册表工具,即使系统或软件重启依旧可依据属性服务中的记录进行相应的初始化工作。还可以用于软件间信息的获取等。
属性服务的初始化早于zygote进程,写操作采用socket进程来跨进程通信,读操作采用共享内存来读取。
具体如何初始化启动通信可参考文末的2、3。
2、Android 属性服务研究
3、android 开机启动流程分析(04)init启动中关键服务-属性服务
zygote进程创建了应用程序进程和SystemServer进程
int main(int argc, char** argv) {
parser.ParseConfig("/init.rc");
}
init.rc是一个非常重要的配置文件,它是由Android初始化语言编写的脚本,共包含5中类型语句(参考4),如下所示。查看下面代码可以发现,会启动classname为main的service,而我们在特定系统的rc文件中发现init新建了一个名为zygote的进程其classname为main,则就代表启动了zygote。
执行do_class_start最终会fork子进程并启动这个进程,那么zygote进程启动起来了。
//system/core/rootdir/init.rc
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
// ro.zygote变量,它可以被理解为一个环境变量
import /init.${ro.zygote}.rc
// 初始化创建一系列文件
on zygote-start && property:ro.crypto.state=unencrypted
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=unsupported
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on nonencrypted
class_start main
class_start late_start
....
ro.zygote变量,它可以被理解为一个环境变量,这里我们看64里面的。
init进程会创建名为zygote的进程,程序的执行路径为
/system/bin/app_process64,zygote的classname为main
//system/core/rootdir/init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
app_process关联到app_main中,由于zygote进程包含有zygote则runtime会进入分之一中,进入具体的start方法这里会解析字符串和args最终会jni调用com/android/internal/os/ZygoteInit 中的main函数
//frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]){
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
我们看看AndroidRumtime具体做了哪些操作
//frameworks/base/core/jni/AndroidRuntime.cpp
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*
* Passes the main function two arguments, the class name and the specified
* options string.
*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
/*
* We want to call main() with a String array with arguments in it.
* At present we have two arguments, the class name and an option string.
* Create an array to hold them.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
assert(optionsStr != NULL);
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
// ****************************
// 通过JNI调用ZygoteInit的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
}
如上所示AndroidRuntime 首先启动了java虚拟机,然后注册了JNI方法,再然后解析传递的的路径jni调用java层的main方法
好了终于c++层切换到我们的java框架层了。我们深入探索到ZygoteInit.java去看看内部做了哪些操作。
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
// Zygote goes into its own process group.
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
final Runnable caller;
try {
// Report Zygote start time to tron unless it is a runtime restart
...
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
//******
// 1、创建一个Service端的socket,sockerName为zygote
zygoteServer.registerServerSocket(socketName);
// 2、第一次加载会预加载类和资源
if (!enableLazyPreload) {
preload(bootTimingsTraceLog);
....
}
// 3、fork systemServer
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
// 4、等待am请求,早于fork进程
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
}
在zygote进程中创建了一个名为 ANDROID_SOCKET_zygote的socket,
用途是在该socket上等待AMS请求zygote进程来创建新的应用程序进程
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
public static void main(String argv[]) {
...
zygoteServer.registerServerSocket(socketName);
...
caller = zygoteServer.runSelectLoop(abiList);
}
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
class ZygoteServer {
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
// socket创建并返回
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
//****
//无限循环等待AMS请求
while (true) {
...
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
//服务端与客户端连接了
if (i == 0) {
// *****************
// 添加入队列 接收到消息
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
ZygoteConnection connection = peers.get(i);
// ****************
//创建新的应用程序进程
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
// We're in the child. We should always have a command to run at this
// stage if processOneCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
// We're in the server - we should never have any commands to run.
if (command != null) {
throw new IllegalStateException("command != null");
}
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
} catch (Exception e) {
if (!mIsForkChild) {
ZygoteConnection conn = peers.remove(i);
conn.closeSocket();
fds.remove(i);
} else {
Log.e(TAG, "Caught post-fork exception in child process.", e);
throw e;
}
}
}
}
}
}
具体接收到AMS通知新进程的代码如下所示,接收到通知后会由
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
class ZygoteConnection {
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
fd = null;
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
public static void main(String argv[]) {
....
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
....
}
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
// 从zygote进程fork出一个systemServer
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// 因为子进程会复刻父进程,所以在SystemService中关闭socket
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
if (parsedArgs.invokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
/*
* 1、路径类加载
*/
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
* 执行zygoteInit方法
*/
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
// 启动binder线程池
ZygoteInit.nativeZygoteInit();
// 进入SystemServer的main方法
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
}
这里创建线程池就不去深究了
systemServer启动了Binder线程池,那么就可以通过binder线程池进行通信。
下面我们来查看下SystemServer是如何唤醒的
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
final Arguments args = new Arguments(argv);
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
private static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
// ******
// 最终反射调用 SystemServer的main方法
// ******
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
}
//frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
/**
* The main entry point from zygote.
* 从zygote进入的主要入口
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
// 创建消息looper
Looper.prepareMainLooper();
// Initialize native services.
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
// 创建系统的context
createSystemContext();
// ***** Create the system service manager.
// 创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
// Start services.
try {
traceBeginAndSlog("StartServices");
// 启动引导服务
startBootstrapServices();
// 启动核心服务
startCoreServices();
// 启动其他服务
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
throw ex;
} finally {
traceEnd();
}
// Loop forever.
// 执行loop循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
/*
* 创建context
*/
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
}
我们以启动UserManagerService来简单了解下SystemServiceManager如何启动一个服务的。
private void startBootstrapServices() {
...
traceBeginAndSlog("StartUserManagerService");
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
traceEnd();
}
//frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public class SystemServiceManager {
// Services that should receive lifecycle events.
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
}
//frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java
public class UserManagerService extends IUserManager.Stub {
public static class LifeCycle extends SystemService {
private UserManagerService mUms;
/**
* @param context
*/
public LifeCycle(Context context) {
super(context);
}
@Override
public void onStart() {
mUms = UserManagerService.getInstance();
/**
* 调用了SystemService的publishBinderService方法
*/
publishBinderService(Context.USER_SERVICE, mUms);
}
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mUms.cleanupPartialUsers();
}
}
}
}
下面去探究 SystemService的publishBinderService 调用了哪个方法,可以发现实际上是将service添加到了ServiceManager中
//frameworks/base/services/core/java/com/android/server/SystemService.java
// 所有生命周期方法都是从系统服务器的主循环线程调用的
public abstract class SystemService {
protected final void publishBinderService(String name, IBinder service) {
publishBinderService(name, service, false);
}
final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
ServiceManager.addService(name, service, allowIsolated);
}
}
我们继续看下ServiceManager的addService方法,那么又通过IServiceManager的实现类进行添加
//frameworks/base/core/java/android/os/ServiceManager.java
public final class ServiceManager {
private static IServiceManager sServiceManager;
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
}
最终添加到了Binder线程池中了,这里对binder线程池不是特别理解,后续需要研究。
service进入binder线程池后也就可以跨进程进行通信了。
public class BinderInternal {
/**
* Return the global "context object" of the system. This is usually
* an implementation of IServiceManager, which you can use to find
* other services.
*/
public static final native IBinder getContextObject();
}
//frameworks/base/core/java/android/os/ServiceManagerNative.java
public abstract class ServiceManagerNative extends Binder implements IServiceManager{
/**
* Cast a Binder object into a service manager interface, generating
* a proxy if needed.
*/
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
public ServiceManagerNative()
{
attachInterface(this, descriptor);
}
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
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;
}
public IBinder checkService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
// 将service写入了对象池中
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
}
}
此时各种系统服务其实是运行在SystemServer进程中的,那么我们在应用中调用各种系统服务其实就是在进程间通信了。后续我也会去多多研究binder,毕竟大牛博主都说了binder是跨向Android高级的第一步,加油。
参考文章
1、Android 8.0 系统启动流程之Linux内核启动–kernel_init进程(三)
2、Android 属性服务研究
3、android 开机启动流程分析(04)init启动中关键服务-属性服务
4、安卓初始化语言
Android zygote 进程的启动过程分析
参考书籍
<