Activity是如何被启动的

我们点击launcher桌面图标后Activity是如何被启动并显示出来的,下面是流程,我们一步步的讲

Launcher
 ↓
ATMS
 ↓
AMS
 ↓
ProcessList.startProcessLocked()
 ↓
ZygoteProcess.start()
 ↓
Zygote Socket
 ↓
Zygote进程
 ↓
fork()
 ↓
新App进程
 ↓
ActivityThread.main()

Launcher是什么?

Launcher 本质上就是一个 App,而且它的首页就是一个 Activity。
如我的小米手机我查看当前栈顶的Activity,我这里的ll和llf是我自定义的bat就是查看Activity和Fragment的

image.png

标红的Launcher就是一个 activity,我们通过这个图会发现小米手机的桌面app是com.miui.home,图标该有的id也是有的。也就是说点击图标就相当点给这个图标设置了点击事件 一样
image.png

AOSP中的Launcher

源码位置:
packages/apps/Launcher3
查看源码的地址:https://cs.android.com/

image.png

看注释

/**
 * Default launcher application. 默认 启动器 应用程序
 */
public class Launcher extends StatefulActivity<LauncherState>
        implements Callbacks, InvariantDeviceProfile.OnIDPChangeListener,
        PluginListener<LauncherOverlayPlugin> {
}

这个Activity也有布局填充和获取View设置点击事件


image.png

在这里可以证实上面说得不错,就是inflate出了View


image.png

ItemInflater 的作用:根据 ItemInfo 的类型(应用、快捷方式、文件夹、小部件等)创建对应的 View,并在创建时设置点击监听器
image.png
  mItemInflater = new ItemInflater<>(this, mAppWidgetHolder, getItemOnClickListener(),
                mFocusHandler, new CellLayout(mWorkspace.getContext(), mWorkspace));
image.png

看下面的调用链

/**
     * Event handler for an app shortcut click.
     *
     * @param v The view that was clicked. Must be a tagged with a {@link WorkspaceItemInfo}.
     */
    public static void onClickAppShortcut(View v, WorkspaceItemInfo shortcut, Launcher launcher) {
        if (shortcut.isDisabled() && handleDisabledItemClicked(shortcut, launcher)) {
            return;
        }

        // Check for abandoned promise 很多定义系统预装快捷方式点击的时候会触发下面的方法下载应用
        if ((v instanceof BubbleTextView) && shortcut.hasPromiseIconUi()
                && (!Flags.enableSupportForArchiving() || !shortcut.isArchived())) {
            String packageName = shortcut.getTargetPackage();
            if (!TextUtils.isEmpty(packageName)) {
                onClickPendingAppItem(
                        v,
                        launcher,
                        packageName,
                        (shortcut.runtimeStatusFlags
                                & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0);
                return;
            }
        }

        // Start activities 正常启动应用
        startAppShortcutOrInfoActivity(v, shortcut, launcher);
    }

image.png

Launcher的startActivitySafely是从ActivityContext继承过来的


image.png

方法解读:
Android Launcher 中用于安全启动 Activity 的默认方法(default)。它综合考虑了安全模式、快捷方式支持、用户空间、动画回调等场景,确保启动过程健壮且可追踪。
参数解读:
v:触发启动的视图,用于获取启动动画选项及视图边界(作为 Intent#setSourceBounds 的源区域)。
intent:基础启动意图,会被添加 FLAG_ACTIVITY_NEW_TASK 标志。
item:与视图关联的项信息(如应用图标、快捷方式、小部件等),可为 null。
返回值:
若活动成功启动,返回一个 RunnableList(通常用于监听动画结束的回调列表);
若启动失败或被安全模式拦截,返回 null。

default RunnableList startActivitySafely(
            View v, Intent intent, @Nullable ItemInfo item) {
        Preconditions.assertUIThread();
        Context context = (Context) this;
        /**
        当 Launcher 处于安全模式时,并且非系统应用。
        非系统应用被阻止,并提示错误 Toast,返回 null。
      **/
        if (LauncherAppState.getInstance(context).isSafeModeEnabled()
                && !new ApplicationInfoWrapper(context, intent).isSystem()) {
            Toast.makeText(context, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
            return null;
        }

        boolean isShortcut = (item instanceof WorkspaceItemInfo)
                && item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
                && !((WorkspaceItemInfo) item).isPromise();
        if (isShortcut && !WIDGETS_ENABLED) {
            return null;
        }
        ActivityOptionsWrapper options = v != null ? getActivityLaunchOptions(v, item)
                : makeDefaultActivityOptions(item != null && item.animationType == DEFAULT_NO_ICON
                        ? SPLASH_SCREEN_STYLE_SOLID_COLOR : -1 /* SPLASH_SCREEN_STYLE_UNDEFINED */);
        UserHandle user = item == null ? null : item.user;
        Bundle optsBundle = options.toBundle();
        // Prepare intent 准备intent
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (v != null) {
            intent.setSourceBounds(Utilities.getViewBounds(v));
        }
        try {
            if (isShortcut) {
                String id = ((WorkspaceItemInfo) item).getDeepShortcutId();
                String packageName = intent.getPackage(); //获取了包名
                // Android 7.1+ 的应用快捷方式
                // 你点的不是普通应用图标,而是长按应用图标弹出来的快捷入口(比如长按微信直接点“扫一扫”)
                ((Context) this).getSystemService(LauncherApps.class).startShortcut(
                        packageName, id, intent.getSourceBounds(), optsBundle, user);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                  
                 /***
                  点的是当前登录的这个用户自己的普通应用图标(99% 的情况都属于这里),
                  直接用最普通的方法打开这个应用 —— 就像你从桌面点微信图标一样,这个时候并不知道打开哪个Activity
                  所有信息都在Intent里面。
                 **/
                // Could be launching some bookkeeping activity
                context.startActivity(intent, optsBundle);
            } else {
 /***
  情景还原:
你在手机里开了两个“空间”——比如自己正常用的空间,还有一个工作空间(工作资料)。两个空间就像个独  立的房间,里面的应用不能串着用普通方式打开  
举个例子:
你现在正在自己房间(当前用户),看到桌面上有个钉钉图标,但它其实是工作房间里的钉钉。你一点它所以系统必须换一种方式:找 LauncherApps 这个“管家”,让管家去工作房间里把那个钉钉的主界面启动起来。      
    ***/
                context.getSystemService(LauncherApps.class).startMainActivity(
                        intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
            }
            if (item != null) {
                //日志记录表示打开应用上面的三种情况都会记录
                InstanceId instanceId = new InstanceIdSequence().newInstanceId();
                logAppLaunch(getStatsLogManager(), item, instanceId);
            }
            return options.onEndCallback;
        } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
            Toast.makeText(context, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
        }
        return null;
    }

context.startActivity(intent, optsBundle);

else if (user == null || user.equals(Process.myUserHandle())) {
                 //点的是当前登录的这个用户自己的普通应用图标(99% 的情况都属于这里)
                // 直接用最普通的方法打开这个应用 —— 就像你从桌面点微信图标一样
                // Could be launching some bookkeeping activity
                context.startActivity(intent, optsBundle);
            } 

这里的context 被赋值的地方


image.png

通过继承关系,我们知道了这个context就是Launcher它是Activity的子类


image.png

所以 context.startActivity(intent, optsBundle); 就是Activity的 startActivity

进入了我们可以不借助读网站可以看源码了地方了

image.png

一个应用从桌面点击,也就是 Launcher.startActivitySafely 最终会调到startActivityForResult


image.png

image.png

有个疑问?mInstrumentation 是在Activity的attach里赋值的,但我们点击Launcher上的图标时,我们的应用还在启动我们应用的luancher Activity并没有创建,没有被创建那 mInstrumentation是谁的啊?其实这个阶段 mInstrumentation是启动者的,对于我们的应用(被启动者)这个时候 我们的应用,还有创建阶段。

Instrumentation.execStartActivity方法

android.app.Instrumentation#execStartActivity(android.content.Context, android.os.IBinder, android.os.IBinder, android.app.Activity, android.content.Intent, int, android.os.Bundle)
在 Android 启动流程里,Instrumentation 可以理解成 Activity 启动过程中的“执行官”或者“代理人”,它负责把启动请求发送给ATMS(AMS)
在 Android 启动流程中,Instrumentation 是 ActivityThread 与 Activity 之间的执行代理:
启动 Activity
→ Instrumentation.execStartActivity()
创建 Activity
→ Instrumentation.newActivity()
触发生命周期
→ Instrumentation.callActivityOnXXX()
因此它既负责把启动请求发送给 AMS,又负责在应用进程内创建 Activity 并分发生命周期,是整个 Activity 生命周期中的核心调度者之一。

image.png

image.png

代码解读:

image.png

IBinder b = ServiceManager.getService("activity"); //拿到AMS在Binder驱动中的代理对象
系统启动过程中,AMS 创建出来以后,会向 ServiceManager 注册:
ServiceManager.addService(
Context.ACTIVITY_SERVICE, // "activity"
this, // AMS
true
);
这里的 this 就是:
ActivityManagerService extends IActivityManager.Stub
也就是说:
AMS

IActivityManager.Stub

Binder
AMS 本身就是一个 Binder 服务
ServiceManager.getService("activity") 意思就是"把名字叫 activity 的 Binder 给我"
image.png

总结:返回向MangerService中注册的AMS(ActivityMangerService) Binder的代码对象
IActivityManager am = asInterface(b);
image.png

ActivityManagerNative.getDefault() 跨进程返回的是 ActivityManagerProxy(obj)
image.png

image.png

发送

IActivityManager.Stub.Proxy(client)此时持了AMS的binder代理
mRemote.transact(START_ACTIVITIES_TRANSACTION, data, reply, 0); //进行IPC(跨进程通信)


image.png

对于Binder机制 transact是发送 onTransatct是接收

接收

也要用这个判断 START_ACTIVITIES_TRANSACTION


image.png

再重复记忆: ActivityManagerService,是一个Stub(server)

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {}

IApplicationThread 它也是一个Binder 系统私有API,用于与应用程序通信。应用程序启动时会向活动管理器(AMS)提供该信息,以便活动管理器告知应用需要完成的事情

public interface IApplicationThread extends IInterface {}

IApplicationThread 看上面标红的 IApplicationThread app = ApplicationThreadNative.asInterface(b) 它还是 ServiceManger.get("Activity") ; 上面说的 它是 AMS在Binder驱动中的代码对象

image.png

那 IBinder b = data.readStrongBinder(); 这里的b是什么
b = “调用方(Launcher / App)传过来的 ApplicationThread Binder”
看看调用方,到这里应该明白readStrongBinder了,因为调用方是write
image.png

类的关系

class ApplicationThread extends ApplicationThreadNative;
abstract class ApplicationThreadNative extends Binder implements IApplicationThread;
interface IApplicationThread extends IInterface
class ActivityManagerService extends IActivityManager.Stub
/**
用于与 Activity Manager Service(AMS)通信的系统内部 API。它提供了一组接口,
使应用进程能够回调到 Activity Manager(定义了AMS对处暴露的方法) 应用进程内并拿不到
AMS `ActivityManagerService ams = ??? // 不可能` ,因为AMS运行在SystemServer进程中,所以只能拿到 IActivityManager 这个Proxy
**/

interface IActivityManager extends IInterface
abstract class ActivityManagerNative extends Binder implements IActivityManager
// AMS继承自 IActivityManager.Stub, ActivityManagerNative 实现了 IActivityManager

IActivityManager 定义了AMS对处暴露的方法

image.png

Binder b = ServiceManager.getService("activity"); 返回的这个binder到底是什么?
ServiceManager.getService("activity") 返回的对象是一个远程服务的“代理”对象(Proxy),它实现了 IBinder 接口。它并不是 ActivityManagerService (AMS) 本身,而是你所在App进程与系统服务(AMS)进程进行跨进程通信(IPC)的信使和代表。具体来说,它是 BinderProxy 类型的对象,在Native层对应的是 BpBinder你可以把它理解为AMS在客户端进程中的一个“替身”或“遥控器”:通过它,你的App可以像调用本地方法一样,向远在 system_server 进程的AMS发送请求。
ActivityManagerNative.getDefault()的返回值:类型是 IActivityManager
如果是同进程内:
image.png

image.png

进入到下面


image.png

android.app.ActivityManagerProxy#startActivity
通过上面的说明:这个mRemote就是我们说的 AMS的替身


image.png

上面的发送后会进入AMS的onTransact里处理
com.android.server.am.ActivityManagerService#onTransact
image.png

如何理解后续流程?

首先你要了解理解Binder机制,如果只看源码的话,这块多少会让人懵逼。
我们现在走到了ActivityMangerNative.ActivityMangerProxy() 你记着它是一个BinderProxy,在其StartActivity中的mRemote就通过ServiceManger.get("Activity") 获取的 AMS中的Binder驱动中的代码,通过这个Binder发送出去的信息会被ActivityManagerService接收

image.png

进入其Super,这个时候的this,已经是AMS了也就说虽然super.Transact 进入到了 ActivityMangerNative的onTransact,但些时和this指向是是AMS而非 ActivityManagerProxy了
android.app.ActivityManagerNative#onTransact
image.png

进入到到ActivityManagerServcice的startActivity
下面每一个方法只总结作用
com.android.server.am.ActivityManagerService#startActivity:
“入口转发 + 自动补 userId”,不做任何真正逻辑
com.android.server.am.ActivityManagerService#startActivityAsUser:
com.android.server.am.ActivityStackSupervisor#startActivityMayWait:
解析 Intent
PMS查询目标Activity
获取 ActivityInfo
创建 ActivityRecord
com.android.server.am.ActivityStackSupervisor#startActivityLocked
com.android.server.am.ActivityStackSupervisor#startActivityUncheckedLocked
这里是启动模式处理核心:
处理:
singleTask
singleTop
singleInstance
FLAG_ACTIVITY_NEW_TASK
任务栈复用等。
image.png

image.png

com.android.server.am.ActivityStack#resumeTopActivityInnerLocked
pause当前Activity
切换Task
准备启动目标Activity
com.android.server.am.ActivityStackSupervisor#startSpecificActivityLocked
判断目标进程是否存在,分为不同的启动方式
ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); (如果app不等于null)说明当前应用已经被启动,也就是普通的App内StartActivity,不是启动当前应用的laucherActivity
r.task.stack.setLaunchTime(r);性能中埋点使用的。
我们既然是看Activity的启动流程 那就看这个

 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);

会调用入到
com.android.server.am.ActivityManagerService#startProcessLocked(com.android.server.am.ProcessRecord, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])


image.png
race.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);  // 这个追踪就是我们在 Perfetto上看到的setup时间轴

android.os.Process#startViaZygote
android.os.Process#zygoteSendArgsAndGetResult _它会把参数通过 Socket向Zygote 发送命令,同时会把参数写入到本地,只所以写入本地因为 ZygoteInit.readArgumentList()有读取 _

--runtime-args
--setuid=10086
--setgid=10086
--nice-name=com.demo.app
android.app.ActivityThread

com.android.internal.os.ZygoteInit
Zygote 进程的启动类
通过上面的Process.start把Zygote进程打开
预先初始化部分类,然后在一个 UNIX 域套接字上等待命令。
根据这些命令,派生(fork)出继承 VM 初始状态的子进程。

image.png

image.png

com.android.internal.os.ZygoteConnection#runOnce

 boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            Log.w(TAG, "IOException on command socket " + ex.getMessage());
            closeSocket();
            return true;
        }

        if (args == null) {
            // EOF reached.
            closeSocket();
            return true;
        }

        /** the stderr of the most recent request, if avail */
        PrintStream newStderr = null;

        if (descriptors != null && descriptors.length >= 3) {
            newStderr = new PrintStream(
                    new FileOutputStream(descriptors[2]));
        }

        int pid = -1;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;

        try {
            parsedArgs = new Arguments(args);

            if (parsedArgs.abiListQuery) {
                return handleAbiListQuery();
            }

            if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
                throw new ZygoteSecurityException("Client may not specify capabilities: " +
                        "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
                        ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
            }

            applyUidSecurityPolicy(parsedArgs, peer);
            applyInvokeWithSecurityPolicy(parsedArgs, peer);

            applyDebuggerSystemProperty(parsedArgs);
            applyInvokeWithSystemProperty(parsedArgs);

            int[][] rlimits = null;

            if (parsedArgs.rlimits != null) {
                rlimits = parsedArgs.rlimits.toArray(intArray2d);
            }

            if (parsedArgs.invokeWith != null) {
                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                childPipeFd = pipeFds[1];
                serverPipeFd = pipeFds[0];
                Os.fcntlInt(childPipeFd, F_SETFD, 0);
            }

            /**
             * In order to avoid leaking descriptors to the Zygote child,
             * the native code must close the two Zygote socket descriptors
             * in the child process before it switches from Zygote-root to
             * the UID and privileges of the application being launched.
             *
             * In order to avoid "bad file descriptor" errors when the
             * two LocalSocket objects are closed, the Posix file
             * descriptors are released via a dup2() call which closes
             * the socket and substitutes an open descriptor to /dev/null.
             */

            int [] fdsToClose = { -1, -1 };

            FileDescriptor fd = mSocket.getFileDescriptor();

            if (fd != null) {
                fdsToClose[0] = fd.getInt$();
            }

            fd = ZygoteInit.getServerSocketFileDescriptor();

            if (fd != null) {
                fdsToClose[1] = fd.getInt$();
            }

            fd = null;

            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
        } catch (ErrnoException ex) {
            logAndPrintError(newStderr, "Exception creating pipe", ex);
        } catch (IllegalArgumentException ex) {
            logAndPrintError(newStderr, "Invalid zygote arguments", ex);
        } catch (ZygoteSecurityException ex) {
            logAndPrintError(newStderr,
                    "Zygote security policy prevents request: ", ex);
        }

        try {
            if (pid == 0) {
                // in child
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

                // should never get here, the child is expected to either
                // throw ZygoteInit.MethodAndArgsCaller or exec().
                return true;
            } else {
                // in parent...pid of < 0 means failure
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }
    }

args = readArgumentList(); 读取Process.start传过来的args
从Zygote进程孵化出一个新的子进程,并根据传入的参数进行一些设置,使其具备特定身份和运行环境的应用进程

  pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);

handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); 处理这个孵化出来的新的子进程

image.png

com.android.internal.os.RuntimeInit#zygoteInit
com.android.internal.os.RuntimeInit#applicationInit
image.png

com.android.internal.os.RuntimeInit#invokeStaticMain
通过反射执行ActivityThread.main方法
image.png

为什么说是ActivityThread.main 怎么佐证?
image.png

image.png

可以一下Process的write和 com.android.internal.os.RuntimeInit.Arguments#parseArgs读

image.png

image.png

Process.start中 Zygote参数最后一个是 processClass 它就是ActivityThread
image.png

所以在RuntimeInit中

image.png
image.png

至此比较难懂的流程是结束了,下面总结一下:

1、从Launcher程序的首页 具体是 launcher3/Launcher.java(它是一个Activity)
它有Inflate也有布局容器,通过 ItemInfo的类型创建对应的View,并绑定点击事件,然后通过一系列的调用链最终调用到context.startActivity
android.app.Instrumentation#execStartActivities
(Instrumentation,是ActivityThread与Activity之间的执行代理)负责Activity的启动、创建、生命周期的回调,它负责把启动请求发送给AMS,它是Activity使命周期的核心调度者之一。
IBinder b = ServiceManager.getService("activity"); 获取 AMS 在Binder驱动中的代理对象
ActivityMangerProxy 实现了 IActivityManager (可以看到AMS在了变身)因为 ActivityMangerProxy 实现了 IActivityManager (操作Activity的模板)
IApplicationThread:它也是一个Binder是系统的私有Api,用于与应用程序通信。应用启动时会向AMS提供该信息,以更AMS完成任务时通过 IApplicationThread告知当前应用
android.app.ActivityManagerProxy#startActivity 向AMS发送 启动Activity事务(这里发生了IPC)
com.android.server.am.ActivityManagerService#onTransact (通过 uper.onTransact(code, data, reply, flags))又回去了
com.android.server.am.ActivityManagerService#startActivity
com.android.server.am.ActivityManagerService#startActivityAsUser
com.android.server.am.ActivityStackSupervisor#startActivityMayWait (解析intent 获取ActivityInfo创建 ActivityRecord 等)
com.android.server.am.ActivityStackSupervisor#startActivityLocked
com.android.server.am.ActivityStackSupervisor#startActivityUncheckedLocked(获取启动模式并封装成bundle)
com.android.server.am.ActivityStack#resumeTopActivityLocked(ActivityRecord, android.os.Bundle)
com.android.server.am.ActivityStack#resumeTopActivityInnerLocked (暂停当前前Activity 是否切换Task 准备Activity)

image.png

com.android.server.am.ActivityStackSupervisor#startSpecificActivityLocked
image.png

mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);

com.android.server.am.ActivityManagerService#startProcessLocked(java.lang.String, android.content.pm.ApplicationInfo, boolean, int, java.lang.String, android.content.ComponentName, boolean, boolean, int, boolean, java.lang.String, java.lang.String, java.lang.String[], java.lang.Runnable)
startProcessLocked( app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);

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);
android.os.Process#start
android.os.Process#startViaZygote
android.os.Process#zygoteSendArgsAndGetResult (打开socket连接与zygote进程通信)
android.os.Process#openZygoteSocketIfNeeded (打开socket连接)
然后进入到了 com.android.internal.os.ZygoteInit#main
com.android.internal.os.ZygoteInit#runSelectLoop
com.android.internal.os.ZygoteConnection#runOnce (Zygote进程 fork出一个新的子进程也就是我们当前需要启动的应用,)

 if (pid == 0) {
                // in child
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

                // should never get here, the child is expected to either
                // throw ZygoteInit.MethodAndArgsCaller or exec().
                return true;
            }

com.android.internal.os.ZygoteConnection#handleChildProc
if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); } 这就是设置我们Debug的时候进程的名字
com.android.internal.os.RuntimeInit#zygoteInit
com.android.internal.os.RuntimeInit#applicationInit
com.android.internal.os.RuntimeInit#invokeStaticMain
com.android.internal.os.ZygoteInit.MethodAndArgsCaller#run (最终会执行到了ActivityThread.main)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容