本篇结合上一篇https://blog.youkuaiyun.com/we1less/article/details/117485532?spm=1001.2014.3001.5501
上一篇方法最后调用了
startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
1
startViaZygote() frameworks/base/core/java/android/os/ZygoteProcess.java
最后调用了 zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
注意这块在函数参数部分调用了openZygoteSocketIfNeeded(abi)
private Process.ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
...//以下省略配置参数
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
2
zygoteSendArgsAndGetResult() frameworks/base/core/java/android/os/ZygoteProcess.java
见名知其意 发送参数(就是上面方法配置的)、返回结果 在这里就指代与Socket通信
@GuardedBy("mLock")
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
...
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
...
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
上面代码中的zygoteState.writer是被封装在frameworks/base/core/java/android/os/ZygoteProcess.java类
里面的一个静态内部类public static class ZygoteState
其构造器是这样的
private ZygoteState(LocalSocket socket, DataInputStream inputStream,
BufferedWriter writer, List<String> abiList) {
this.socket = socket;
this.inputStream = inputStream;
this.writer = writer;
this.abiList = abiList;
}
ZygoteState::connect frameworks/base/core/java/android/os/ZygoteProcess.java类
调用构造器的地方是这个静态内部类里面的一个静态方法connect
这个静态方法入参是一个socketAddress
public static ZygoteState connect(String socketAddress) throws IOException {
...
final LocalSocket zygoteSocket = new LocalSocket();
try {
zygoteSocket.connect(new LocalSocketAddress(socketAddress,
LocalSocketAddress.Namespace.RESERVED));
zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());
zygoteWriter = new BufferedWriter(new OutputStreamWriter(
zygoteSocket.getOutputStream()), 256);
} catch (IOException ex) {
try {
zygoteSocket.close();
} catch (IOException ignore) {
}
throw ex;
}
return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
Arrays.asList(abiListString.split(",")));
}
openZygoteSocketIfNeeded frameworks/base/core/java/android/os/ZygoteProcess.java
在这个方法中调用ZygoteState::connect 并将mSocket传入
接下来看mSocket在构造器中初始化
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
...
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
}
...
}
ZygoteProcess frameworks/base/core/java/android/os/ZygoteProcess.java
构造器中将mSocket初始化
接下来看构造器在何时被调用
public ZygoteProcess(String primarySocket, String secondarySocket) {
mSocket = primarySocket;
mSecondarySocket = secondarySocket;
}
Process frameworks/base/core/java/android/os/Process.java
ZygoteProcess在作为Process的成员变量被初始化传入的参数为"zygote"
public static final ZygoteProcess zygoteProcess =
new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);
public static final String ZYGOTE_SOCKET = "zygote";
3
main frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
registerServerSocket(socketName) AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
关于后续的部分可以参考这篇https://blog.youkuaiyun.com/we1less/article/details/116325856?spm=1001.2014.3001.5501
String socketName = "zygote";
这样至此就可以利用Socket进行跨进程通信了
后续的部分其实大致就是 https://blog.youkuaiyun.com/we1less/article/details/117306393?spm=1001.2014.3001.5501
zygoteSendArgsAndGetResult() frameworks/base/core/java/android/os/ZygoteProcess.java 利用Socket将启动参数传递给 AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
在这篇分析文章中说道https://blog.youkuaiyun.com/we1less/article/details/117485532?spm=1001.2014.3001.5501if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 构建启动参数 这个参数是最后剩下的在Zygote中用来反射调用main函数的
也就是说这块反射调用的就是android.app.ActivityThread的main函数
4
main frameworks/base/core/java/android/app/ActivityThread.java
这块调用到了thread.attach(false);
public static void main(String[] args) {
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
5
attach frameworks/base/core/java/android/app/ActivityThread.java
最后这获取了ActivityManagerService的binder并将 final ApplicationThread mAppThread = new ApplicationThread(); 的Binder对象传递过去实现双向通信
private class ApplicationThread extends IApplicationThread.Stub 是ActivityThread的一个内部类
此部分调用了ActivityManagerService的Binder方法attachApplication
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
...//不走
}
6
attachApplication frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
Binder.clearCallingIdentity(); 调用Binder的一个静态方法可以用来得到此方法被调的pid
接下来调用attachApplicationLocked
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
7
attachApplicationLocked() frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
https://blog.youkuaiyun.com/we1less/article/details/117485532第18部分已经说了 已经new过了一个ProcessRecord放到mPidsSelfLocked中了
这块利用传递进来的Binder对象thread.bindApplication
最后调用了mStackSupervisor.attachApplicationLocked
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
...
if (app.instr != null) {
//不走这块app.instr为空
} 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);
}
...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
8
bindApplication() frameworks/base/core/java/android/app/ActivityThread.java
sendMessage 发送一个message
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial) {
...
sendMessage(H.BIND_APPLICATION, data);
}
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
handleBindApplication frameworks/base/core/java/android/app/ActivityThread.java
就介绍这一个代码 就是调用了application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);
9 这里接着7讲
attachApplicationLocked() frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
这个函数调用realStartActivityLocked
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
...
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 {
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ top.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
return didSomething;
}
10
realStartActivityLocked() frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
这里调用app.thread.scheduleLaunchActivity
这个app.thread == final ApplicationThread mAppThread = new ApplicationThread(); 关于这块在 5 这里面
然后调用了ApplicationThread (ApplicationThread是ActivityThread的一个内部类) 里面的scheduleLaunchActivity
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
...
}
11
scheduleLaunchActivity() frameworks/base/core/java/android/app/ActivityThread.java
sendMessage(H.LAUNCH_ACTIVITY, r);
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
...
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
}