App 竟然是这样跑起来的 —— Android App_Activity 启动流程分析

}
} else if (v == mAllAppsButton) {
// “所有应用”按钮
onClickAllAppsButton(v);
} else if (tag instanceof AppInfo) {
// 从“所有应用”中启动的应用
startAppShortcutOrInfoActivity(v);
} else if (tag instanceof LauncherAppWidgetInfo) {
// 组件
if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v);
}
}
}

1.1.2 Launcher.onClickAppShortcut

如果是快捷方式图标,则调用 onClickAppShortcut 方法进而调用 startAppShortcutOrInfoActivity 方法:

@Thunk void startAppShortcutOrInfoActivity(View v) {
Object tag = v.getTag();
final ShortcutInfo shortcut;
final Intent intent;
if (tag instanceof ShortcutInfo) {
shortcut = (ShortcutInfo) tag;
// 去除对应的 Intent 对象
intent = shortcut.intent;
int[] pos = new int[2];
v.getLocationOnScreen(pos);
intent.setSourceBounds(new Rect(pos[0], pos[1],
pos[0] + v.getWidth(), pos[1] + v.getHeight()));

} else if (tag instanceof AppInfo) {
shortcut = null;
intent = ((AppInfo) tag).intent;
} else {
throw new IllegalArgumentException(“Input must be a Shortcut or AppInfo”);
}

// 调用 startActivitySafely 方法
boolean success = startActivitySafely(v, intent, tag);
mStats.recordLaunch(v, intent, shortcut);

if (success && v instanceof BubbleTextView) {
mWaitingForResume = (BubbleTextView) v;
mWaitingForResume.setStayPressed(true);
}
}

1.1.3 Launcher.startActivity

获取相应 App 的 Intent 信息之后,调用 startActivity 方法:

private boolean startActivity(View v, Intent intent, Object tag) {
// 启动新的任务栈
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {

if (user == null || user.equals(UserHandleCompat.myUserHandle())) {
StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
try {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
.penaltyLog().build());
// 调用 Activity 的 startActivity 方法
startActivity(intent, optsBundle);
} finally {
StrictMode.setVmPolicy(oldPolicy);
}
} else {
launcherApps.startActivityForProfile(intent.getComponent(), user,
intent.getSourceBounds(), optsBundle);
}
return true;
} catch (SecurityException e) {

}
return false;
}

1.1.4 Activity.startActivity

这里最终调用了 Activity 中的 startActivity 方法,并且设置 Flag 为 FLAG_ACTIVITY_NEW_TASK。到此为止,已经跟启动普通的 Activity 流程汇合起来了,继续往下分析。

frameworks/base/core/java/android/app/Activity.java

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
// 第二个参数为 -1 表示不需要回调 onActivityResult 方法
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);
}
}

1.1.5 Activity.startActivityForResult

调用 Activity 的 startActivityForResult 方法

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
// mParent 是当前 Activity 的父类,此时条件成立
if (mParent == null) {
// 调用 Instrumentation 的 execStartActivity 方法
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this,
mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);

} else {

}
}

1.1.6 Instrumentation.execStartActivity

frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {

try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
// 获取 AMS 的代理对象并调用其 startActivity 方法
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException(“Failure from system”, e);
}
return null;
}

1.1.7 ActivityManagerProxy.startActivity

以上过程是在 Launcher App 所在的进程中发生的,在我的另外一篇文章借助 AIDL 理解 Android Binder 机制——AIDL 的使用和原理分析中我们分析了 AIDL 的实现过程,由于远程 Service 跟使用 Service 的 Activity 不在同一个进程中,因此他们之间交互需要通过 Binder IPC 机制的支持,在这个过程中Client 首先获取到 Server 端的代理对象,在 Client 看来 Server 代理对象同样具有 Server 本地对象承诺的能力,因此 Client 可以调用 Server 代理对象跟 Sever 本地对象进行数据交互,Binder 驱动作为桥梁在他们中间起到中间人的作用。

同样,在Android 系统启动流程分析中我们了解到,AMS 是运行在 system_server 线程中的,这时 AMS 就相当于 AIDL 中的远程 Service,App 进程要与 AMS 交互,需要通过 AMS 的代理对象 AMP(ActivityManagerProxy) 来完成,来看 ActivityManagerNative.getDefault() 拿到的是什么:

frameworks/base/core/java/android/app/ActivityManagerNative.java

static public IActivityManager getDefault() {
return gDefault.get();
}

getDefault 是一个静态变量:

private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
// 向 ServiceManager 查询一个 key 为 “activity” 的引用
IBinder b = ServiceManager.getService(“activity”);
if (false) {
Log.v(“ActivityManager”, "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v(“ActivityManager”, "default service = " + am);
}
return am;
}
};

同样,在文章借助 AIDL 理解 Android Binder 机制——Binder 来龙去脉中也讲到过:

ServiceManager 是 Binder IPC 通信过程的核心,是上下文的管理者,Binder 服务端必须先向 ServerManager 注册才能够为客户端提供服务,Binder 客户端在与服务端通信之前需要从 ServerManager 中查找并获取 Binder 服务端的引用。

这里通过 “activity” 这个名字向 ServiceManager 查询 AMS 的引用,获取 AMS 的引用后,调用 asInterface 方法:

static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// 根据 descriptor 查询 obj 是否为 Binder 本地对象,具体过程请看前文中提到的文章
IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
// 如果 obj 不是 Binder 本地对象,则将其包装成代理对象并返回
return new ActivityManagerProxy(obj);
}

因为 AMS 与 Launcher App 不在同一个进程中,这里返回的 IBinder 对象是一个 Binder 代理对象,因此这类将其包装成 AMP(ActivityManagerProxy) 对象并返回,AMP 是 AMN(ActivityManagerNative) 的内部类,查看 AMP 类 :

class ActivityManagerProxy implements IActivityManager {
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}

public IBinder asBinder() {
return mRemote;
}

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {

// 调用号为 START_ACTIVITY_TRANSACTION
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}

public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId) throws RemoteException {

mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}

}

可以看到,AMP 里面将客户端的请求通过 mRemote.transact 进行转发,mRemote 对象正是 Binder 驱动返回来的 Binder Proxy 对象,通过 Binder Proxy,Binder 驱动最终将调用处于 Binder Server 端 AMN 中的 onTransact 方法:

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
// 根据方法调用号 code 决定调用哪个方法
switch (code) {
case START_ACTIVITY_TRANSACTION:
{

// 调用 startActivity 方法
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}

case START_SERVICE_TRANSACTION: {

ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
}

}
}

1.1.8 ActivityManagerService.startActivity

AMN 是一个抽象类,它的 startActivity 为抽象方法,具体的实现在 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 中:

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}

1.2 小结

从 Launcher App 到 AMS 的调用过程中使用了 Binder IPC 机制,如果你已经看了上面提到的我之前写的两篇文章——借助 AIDL 理解 Android Binder 机制——Binder 来龙去脉借助 AIDL 理解 Android Binder 机制——AIDL 的使用和原理分析,并且运行了文章中使用到的 Demo,你应该可以发现,相对于 AIDL 的调用过程,调用方 Launcher App 相当于 AIDL 过程中的 Activity 所在的 App,充当 Clinent 的角色;AMS 相当于远程 Service 的角色,充当 Server 端角色,他们的调用过程总体上都是一样的。

从 Launcher App 到 AMS 的时序图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. AMS —— zygote

2.1 调用过程分析

2.1.1 ActivityManagerService.startActivityAsUser

接着从 AMS 的 startActivityAsUser 方法开始分析:

@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller(“startActivity”);
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, “startActivity”, null);
// TODO: Switch to user app stacks here.
// 调用 ActivityStarter 的 startActivityMayWait 方法
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null);
}

2.1.2 ActivityStarter.startActivityMayWait

继续跟进 frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {

synchronized (mService) {

// 调用 startActivityLocked 方法
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask);

return res;
}
}

2.1.3 ActivityStarter.startActivityLocked

查看 startActivityLocked 方法:

final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {

// 调用 doPendingActivityLaunchesLocked 方法,传入 false 参数
doPendingActivityLaunchesLocked(false);

return err;
}

2.1.4 ActivityStarter.doPendingActivityLaunchesLocked

查看 doPendingActivityLaunchesLocked 方法:

final void doPendingActivityLaunchesLocked(boolean doResume) {
while (!mPendingActivityLaunches.isEmpty()) {
final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
try {
// 调用 startActivityUnchecked 方法
final int result = startActivityUnchecked(pal.r, pal.sourceRecord, null, null,
pal.startFlags, resume, null, null);
postStartActivityUncheckedProcessing(pal.r, result, mSupervisor.mFocusedStack.mStackId,
mSourceRecord, mTargetStack);
} catch (Exception e) {
Slog.e(TAG, “Exception during pending activity launch pal=” + pal, e);
pal.sendErrorResult(e.getMessage());
}
}
}

2.1.5 ActivityStarter.startActivityUnchecked

查看 startActivityUnchecked 方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {

// 调用 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked 方法
mSupervisor.resumeFocusedStackTopActivityLocked();

return START_SUCCESS;
}

2.1.6 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target,
ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
// 调用 ActivityStack 的 resumeTopActivityUncheckedLocked 方法
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
}
return false;
}

2.1.7 ActivityStack.resumeTopActivityUncheckedLocked

查看 ActivityStack 的 resumeTopActivityUncheckedLocked 方法:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {

try {

// 调用 resumeTopActivityInnerLocked 方法
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}

2.1.8 ActivityStack.resumeTopActivityInnerLocked

查看 resumeTopActivityInnerLocked 方法:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

final ActivityRecord next = topRunningActivityLocked();

if (next.app != null && next.app.thread != null) {

} else {

if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
// 调用 ActivityStackSupervisor 的 startSpecificActivityLocked 方法
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}

if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}

2.1.9 ActivityStackSupervisor.startSpecificActivityLocked

回到 ActivityStackSupervisor 的 startSpecificActivityLocked 方法:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// 当前 Activity 附属的 Application
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime®;
// 如果 Application 已经运行
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !“android”.equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "

  • r.intent.getComponent().flattenToShortString(), e);
    }
    }
    // 启动新进程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
    “activity”, r.intent.getComponent(), false, false, true);
    }

首先,在方法中获取了当前 Activity 附属的 Application,如果已经在运行了,说明这个 App 是已经被启动过了的,这时候调用 realStartActivityLocked 方法就可以进入下一步的流程了,同一个 App 中不同 Activity 的相互启动就是走的这个流程。当 Application 没有运行的时候,就需要调用 AMS 的 startProcessLocked 方法启动一个进程去承载它然后完成后续的工作,顺便铺垫一下,当新进程被启动完成后还会调用回到这个方法,查看 AMS 的 startProcessLocked 方法:

2.1.10 ActivityManagerService.startProcessLocked

final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid /, keepIfLarge,
null /
ABI override /, null / entryPoint /, null / entryPointArgs /,
null /
crashHandler */);
}

2.1.11 ActivityManagerService.startProcessLocked

调用 startProcessLocked 方法:

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler){

startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime, “startProcess: done starting proc!”);
return (app.pid != 0) ? app : null;
}

2.1.12 ActivityManagerService.startProcessLocked

调用 startProcessLocked 的重载方法:

private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs){

try {

// 调用 Process 的 start 方法
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);

} catch (RuntimeException e) {

}
}

2.1.13 Process.start

frameworks/base/services/core/java/android/os/Process.java

public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] zygoteArgs) {
try {
// 调用 startViaZygote 方法
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
“Starting VM process through Zygote failed”);
throw new RuntimeException(
“Starting VM process through Zygote failed”, ex);
}
}

2.1.14 Process.startViaZygote

查看 startViaZygote 方法:

private static 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[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {

// 调用 zygoteSendArgsAndGetResult 方法,传入 openZygoteSocketIfNeeded 的返回值
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}

2.1.15 Process.zygoteSendArgsAndGetResult、Process.openZygoteSocketIfNeeded

查看 zygoteSendArgsAndGetResult 方法:

private static ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList 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();

// Should there be a timeout on this?
ProcessStartResult result = new ProcessStartResult();

// 等待 socket 服务端(即zygote)返回新创建的进程pid;
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);
}
}

在 zygoteSendArgsAndGetResult 中等待 Socket 服务端,也就是 zygote 进程返回创建新进程的结果,这里 zygoteState 参数是由 openZygoteSocketIfNeeded 方法返回的,openZygoteSocketIfNeeded 方法则负责根据 abi 向 Zygote 进程发起连接请求:

private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
// 向主zygote发起connect()操作
primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx(“Error connecting to primary zygote”, ioe);
}
}

if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}

if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
// 当主zygote没能匹配成功,则采用第二个zygote,发起connect()操作
secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx(“Error connecting to secondary zygote”, ioe);
}
}

if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}

throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}

2.2 小结

如果是从桌面新启动一个 App 中的 Activity,此时是没有进程去承载这个 App 的,因此需要通过 AMS 向 zygote 继承发起请求去完成这个任务,AMS 运行在 system_server 进程中,它通过 Socket 向 zygote 发起 fock 进程的请求,从 AMS 开始的调用时序图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. zygote —— ActivityThread

3.1 调用过程分析

3.1.1 ZygoteInit.main

Android 系统启动流程分析 文中提到过 zygote 进程的其中一项任务就是:

调用 registerZygoteSocket() 函数建立 Socket 通道,使 zygote 进程成为 Socket 服务端,并通过 runSelectLoop() 函数等待 ActivityManagerService 发送请求创建新的应用程序进程。

zygote 终于要再次上场了!接下来从 ZygoteInit.java 的 main 方法开始回顾一下 zygote 进程的工作:

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
try {

runSelectLoop(abiList);

} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}

3.1.2 ZygoteInit.runSelectLoop

查看 runSelectLoop 方法:

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {

// 循环读取状态
while (true) {

for (int i = pollFds.length - 1; i >= 0; --i) {
// 读取的状态不是客户端连接或者数据请求时,进入下一次循环
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {// i = 0 表示跟客户端 Socket 连接上了
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {// i > 0 表示接收到客户端 Socket 发送过来的请求
// runOnce 方法创建一个新的应用程序进程
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}

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

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

Android开发除了flutter还有什么是必须掌握的吗?

相信大多数从事Android开发的朋友们越来越发现,找工作越来越难了,面试的要求越来越高了

除了基础扎实的java知识,数据结构算法,设计模式还要求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;

点击文档前往获取面试资料与视频教程;【阿里P7级别Android架构师技术脑图+全套视频】

技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-6NcRXZMc-1710831624929)]
[外链图片转存中…(img-OmbtvNZD-1710831624929)]
[外链图片转存中…(img-cgZXiWEt-1710831624929)]
[外链图片转存中…(img-kxeJ2hB8-1710831624930)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-iLso6UFB-1710831624930)]

Android开发除了flutter还有什么是必须掌握的吗?

相信大多数从事Android开发的朋友们越来越发现,找工作越来越难了,面试的要求越来越高了

除了基础扎实的java知识,数据结构算法,设计模式还要求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;

点击文档前往获取面试资料与视频教程;【阿里P7级别Android架构师技术脑图+全套视频】

[外链图片转存中…(img-fhTuvHBQ-1710831624930)]

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值