Android启动流程分析(4)-launcher进程

前言

在system_server进程启动的流程中,system_server在启动其他服务的流程中,会去调用AMS的systemReady()方法,上一篇说这部分就会去启动launcher应用和和系统ui,然后这一篇就分析一下launcher应用的具体启动流程。

在系统服务的引导服务中,会启动PMS服务,PMS服务会去扫描检测手机中的系统应用和用户安装的非系统应用,launcher应用也是在PMS启动阶段进行扫描,并将其清单文件对应的信息解析完成,在后续调用AMS的systemReady()方法,launcher应用的信息已经解析完成了

#ActivityManagerService.java
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
            t.traceBegin("resumeTopActivities");
            mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
            t.traceEnd();
    }

mAtmInternal就是AMS中持有的ATMS的binder引用,就会执行到ATMS的resumeTopActivities

//#ActivityTaskManagerService.java
public void resumeTopActivities(boolean scheduleIdle) {
            synchronized (mGlobalLock) {
              //会执行RootWindowContainer的对应方法
                mRootWindowContainer.resumeFocusedStacksTopActivities();
                if (scheduleIdle) {
                    mStackSupervisor.scheduleIdle();
                }
            }
        }

//RootWindowContainer.java
boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
            if (!resumedOnDisplay) {
                final ActivityStack focusedStack = display.getFocusedStack();
                if (focusedStack != null) {
                    //进入这个流程
                    result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
                } else if (targetStack == null) {
                    result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                            display.getDefaultTaskDisplayArea());
                }
            }
        }
        return result;
    }

//ActivityStack.java
//step1
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        boolean result = false;
        try {
            mInResumeTopActivity = true;
            //执行这个方法
            result = resumeTopActivityInnerLocked(prev, options);
            final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
        } finally {
        }

        return result;
    }
//step2
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
      if (!hasRunningActivity) {
            // There are no activities left in the stack, let's look somewhere else.
            //Launcher应用进程启动之前是没有activity的,会继续执行
            return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
        }
}
//step3
private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
            ActivityOptions options) {
        final String reason = "noMoreActivities";
        //launcher应用启动就是执行这个关键的resumeHomeActivity方法
            //又回到了RootWindowContainer.java类
        return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea());
}

//RootWindowContainer.java
ActivityTaskManagerService mService;//成员属性可以看出这个mService就是ATMS

boolean resumeHomeActivity(ActivityRecord prev, String reason,
            TaskDisplayArea taskDisplayArea) {
        final ActivityRecord r = taskDisplayArea.getHomeActivity();
        final String myReason = reason + " resumeHomeActivity";

            //继续调用执行
        return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea,
                false /* allowInstrumenting */, false /* fromHomeKey */);
}

boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
            boolean allowInstrumenting, boolean fromHomeKey) {
            //获取ATMS的startController,去启动launcher
        mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
                taskDisplayArea);
        return true;
    }

通过一系列的状态判断和方法调用,最终会回到跟activity管理密切相关的ATMS类,去执行ActivityStartController类中的启动方法

#ActivityStartController.ava
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
            TaskDisplayArea taskDisplayArea) {
            //获取ActivityStarter的实例,去执行execute方法
        mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                .setOutActivity(tmpOutRecord)
                .setCallingUid(0)
                .setActivityInfo(aInfo)
                .setActivityOptions(options.toBundle())
                .execute();
    }
//通过obtainStarter去获取一个ActivityStarter实例
ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

其他launcher应用的启动会执行到ActivityStarter类的execute方法,从类名上看,这就是一个专注于启动activity的类,跟应用开发的关系还是很密切,继续往后续代码看

#ActivityStarter
//step1
int execute() {
        try {
            int res;
            synchronized (mService.mGlobalLock) {
                //上面的逻辑主要是对mRequest参数进行一些状态缺省判断
                //下一步的主要执行逻辑
                res = executeRequest(mRequest);//step2
                return getExternalResult(mRequest.waitResult == null ? res
                        : waitForResult(res, mLastStartActivityRecord));
            }
        } finally {
        }
    }

//step2
private int executeRequest(Request request) {
            //会创建两个ActivityRecord对象,Activity的启动是会传当前的context,方便activity的栈的管理
        ActivityRecord sourceRecord = null;//from
        ActivityRecord resultRecord = null;//to
  
            //后续的执行逻辑,前面就是对参数的各种处理逻辑
            //step3
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);

        return mLastStartActivityResult;
}

//step3
private int startActivityUnchecked() {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            //step4
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } finally {}
  
        return result;
    }

//step4
int startActivityInner() {
   //launcher启动的关键方法
   mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
}

//step5
#RootWindowContainer.java
boolean resumeFocusedStacksTopActivities() {
         result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
     return result;
}

//step6
#ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
   boolean result = false;
   result = resumeTopActivityInnerLocked(prev, options);
     return result;
}

//step7
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        mStackSupervisor.startSpecificActivity(next, true, false);
}

//step8
#ActivityStackSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
            //这个用来获取需要启动的activity的进程,看进程是否存在
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                //应用进程存在,执行这个方法
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {}
            knownToBeDead = true;
        }
        final boolean isTop = andResume && r.isTopRunningActivity();
        //如果应用进程不存在,执行这个方法,去通知zygote符合新的进程
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

通过上面一些列的方法调用,最终会执行到判断进程是否存在的启动Activity的逻辑,这部分跟应用进程里面startactivity流程相关

目前的流程分析是通过system_server进程去启动launcher进程,那么launcher进程就是不存在的,就会执行到ActivityTaskManagerService的startProcessAsync创建进程的方法

#ActivityTaskManagerService.java
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
            String hostingType) {
        try {
            // ATMS lock held.
           //这类会通过handler去发生一个message
           //message里面携带的参数就是需要执行的逻辑
            final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                    isTop, hostingType, activity.intent.getComponent());
            mH.sendMessage(m);
        } finally {}
    }

当应用进程不存在的时候,ATMS中会通过handler和messge机制进行消息传递,消息的内容就是需要执行的逻辑(ActivityManagerInternal::startProcess),那这个就会执行到AMS的方法中

#ActivityManagerService
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
                boolean isTop, String hostingType, ComponentName hostingName) {
            try {
                synchronized (ActivityManagerService.this) {
                    // preempted by other processes before attaching the process of top app.
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName, isTop),
                            ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                            false /* isolated */, true /* keepIfLarge */);
                }
            } finally {}
        }

//继续调用到这个方法
final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
                    //下一步执行
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                keepIfLarge, null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }

#ProcessList.java
 boolean startProcessLocked() {
         try {
                 //注意这里的传入参数的全类目,后续的启动中会用到  
                 final String entryPoint = "android.app.ActivityThread";

                    //下一步会执行startProcess,启动进程
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
            } catch (RuntimeException e) {}
  
            return app.pid > 0;
}

//进一步调用会执行到Process.java类的start方法
private Process.ProcessStartResult startProcess() {
                   startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                        isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                        whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
   
 }

#Process.java
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

public static ProcessStartResult start() {
            //参数很多就省略了,方便观看执行逻辑
            //会执行到ZygoteProcess.java的start方法
        return ZYGOTE_PROCESS.start();
    }
  • 这里需要注意,传入的参数全类目是"android.app.ActivityThread"

接下来就会执行到ZygoteProcess的start()方法

#ZygoteProcess.java
public final Process.ProcessStartResult start(...) {
        try {
            //继续执行到startViaZygote方法
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
        }
}

 private Process.ProcessStartResult startViaZygote(...){
    ArrayList<String> argsForZygote = new ArrayList<>();
            //跟forkSystemServer一样,会添加一些的启动参数
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        argsForZygote.add("--runtime-flags=" + runtimeFlags);
            ...
   
         //进程的名称属性
       if (niceName != null) {
            argsForZygote.add("--nice-name=" + niceName);
        }
   
       synchronized(mLock) {
         //设置完属性后,就会调用此方法
         //第一个参数openZygoteSocketIfNeeded,从名字可以看出是通过socket跟zygote进程通信
         return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
 }

我们前面知道所有的应用进程跟system_server进程一样,都是由zygote进程fork生成的,而且在zygote进程中会有一个socket等待消息的通知去处理生成新的进程,执行到这一步,就能跟前面的流程关联起来了

#ZygoteProcess.java
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            attemptConnectionToPrimaryZygote();
                        //primary跟下面的secondary就是zygote流程中提到的64位和32位的兼容模式
            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }

            if (mZygoteSecondarySocketAddress != null) {
                attemptConnectionToSecondaryZygote();
                if (secondaryZygoteState.matches(abi)) {
                    return secondaryZygoteState;
                }
            }
        } catch (IOException ioe) {
        }
}

//启动主位数zygote连接
private void attemptConnectionToPrimaryZygote() throws IOException {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            //这里可以看出后续的执行流程就是去调用connect方法建立socket连接
            primaryZygoteState =
                    ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
        }
}

//兼容位数的zygote连接,代码逻辑跟上面一致
private void attemptConnectionToSecondaryZygote() throws IOException {
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            secondaryZygoteState =
                    ZygoteState.connect(mZygoteSecondarySocketAddress,
                            mUsapPoolSecondarySocketAddress);
        }
}

//建立连接
static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
                @Nullable LocalSocketAddress usapSocketAddress)
                throws IOException {

                  //创建当前进程的socket对象
            final LocalSocket zygoteSessionSocket = new LocalSocket();

            try {
                //建立连接
                zygoteSessionSocket.connect(zygoteSocketAddress);
                //输入输出流对象创建
                zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
                zygoteOutputWriter =
                        new BufferedWriter(
                                new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),
                                Zygote.SOCKET_BUFFER_SIZE);
            } catch (IOException ex) {}

            return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
                                   zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
                                   getAbiList(zygoteOutputWriter, zygoteInputStream));
        }

通过这一系列的操作就创建好了当前进程的Socket对象和输入输出流对象,接下来就要通过这个socket通道去进行消息的发送了,往上回一步,创建socket对象是方法的第一个参数,就回到对应的方法部分

#ZygoteProcess.java
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
            //处理参数
        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";

        if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
            try {
                //执行到这个方法
                return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
            } catch (IOException ex) {}
        }

        return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    }

private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr)
            throws ZygoteStartFailedEx, IOException {
        try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
            final BufferedWriter usapWriter =
                    new BufferedWriter(
                            new OutputStreamWriter(usapSessionSocket.getOutputStream()),
                            Zygote.SOCKET_BUFFER_SIZE);
            final DataInputStream usapReader =
                    new DataInputStream(usapSessionSocket.getInputStream());

            //这个地方就是进行消息的写入和发送
            usapWriter.write(msgStr);
            usapWriter.flush();

            Process.ProcessStartResult result = new Process.ProcessStartResult();
            result.pid = usapReader.readInt();
          
            if (result.pid >= 0) {
                return result;
            } else {
            }
        }
    }
小结

到这一步我们从systemServer进程的启动其他服务的流程中,走到AMS的systemReady方法,然后AMS里面去一些的调用启动topActivity,发现APP进程不存在,就通过AMS创建socket对象跟Zygote进程连接并发送消息,在Zygote进程中,我们前面分析了创建了socket通道,并会进入循环等待消息的到来,到这一步,就需要就分析Zygote进程循环等待消息后,接收到消息的处理,去fork新的app进程
上面涉及的类比较多,附上对应的流程图


启动app进程给zygote进程发消息的流程图.jpg
#ZygoteInit.java
public static void main(String argv[]) {
    zygoteServer = new ZygoteServer(isPrimaryZygote);
    if (startSystemServer) {
      //之前分析到这,启动systemserver进程
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);  //fork systemserver

       if (r != null) {
          r.run();
          return;
         }
    }

    caller = zygoteServer.runSelectLoop(abiList);  //zygote 进程进入无限循环,处理请求
}

Runnable runSelectLoop(String abiList) {
     while (true) {
       
            int pollReturnValue;
            try {
                //通过epoll机制进行循环等待
                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);  //等到事件到来
            } catch (ErrnoException ex) {
            }
       
           if (pollReturnValue == 0) {

            } else {
             //有消息来了
                boolean usapPoolFDRead = false;

                //注意这里是倒序的,即优先处理已建立链接的信息,后处理新建链接的请求
                while (--pollIndex >= 0) {
                    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                        continue;
                    }

                    //server socket 最新加入 fds, 因此这里就是 server socket 收到数据
                    if (pollIndex == 0) {
                        // Zygote server socket

                        //收到新的建立通信的请求,建立通信连接
                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                        //加入到 peers 和 socketFDs,即下一次也开始监听
                        peers.add(newPeer);
                        socketFDs.add(newPeer.getFileDescriptor());

                    } else if (pollIndex < usapPoolEventFDIndex) {   //其他通信连接收到数据
                        // Session socket accepted from the Zygote server socket
                        try {
                            ZygoteConnection connection = peers.get(pollIndex);
                            //接收到请求后的具体执行逻辑
                            final Runnable command = connection.processOneCommand(this);
                        }
                    }
                }
           }
     }
}

//接下来会执行到ZygoteConnection的processOneCommand方法
#ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
    int pid;
    //通过forkAndSpecialize去fork出新的进程
    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
                parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
  
   try {
            if (pid == 0) {
                // in child
                zygoteServer.setForkChild();
               //跟systemserver进程一样,由zygote孵化来的子进程都需要关闭socket连接,释放资源
                zygoteServer.closeServerSocket();
                //返回的最终执行的runnable
                return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
            }
        }
}

//后续的孵化流程就跟启动systemserver类似
#Zygote.java
static int forkAndSpecialize(){
   //system_server: nativeForkSystemServer
   int pid = nativeForkAndSpecialize();
}

#com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(){
   //这个方法就是跟systemserver进程的孵化方法一致了
   pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
}

//生成需要执行的Runnable
#ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
        closeSocket();
        Zygote.setAppProcessName(parsedArgs, TAG);

        if (parsedArgs.mInvokeWith != null) {
        } else {
            if (!isZygote) {
                return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mDisabledCompatChanges,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            } else {
                return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            }
        }
    }

到这一步,AMS就通过zygote启动了launcher应用进程,从这可以看出,启动systemserver进程和普通的应用进程都是由zygote去进行了,大体流程也是类似的,返回了Runable对象后会去执行run方法,接下来的ZygoteInit.zygoteInit()就是在SystemServr启动流程中有分析过的方法

->ZygoteInit.zygoteInit()
->RuntimeInit.applicationInit()
->findStaticMain()

而在后续的流程中,就是通过反射去执行对应类的main方法,在forkSystemServer方法中,最终执行的就是SystemServer.main(),而启动应用进程,我们再ProcessList.java类中启动进程,传入的参数就是android.app.ActivityThread",所以launcher应用的启动后续就会去执行ActivityThread.main()方法

小结

通过一些列的流程分析,走到了我们熟悉的ActivityThread.main()方法,这个方法就是应用进程启动的入口,里面就会是执行主线程的looper的启动,执行application.oncreat()方法等,具体的launcher应用的创建和显示,和普通的app应用流程一样的,后续会分析PMS解析应用四大组件后再分析app的启动到显示到桌面的流程

点击桌面图标的流程和launcher启动流程也是一样的,通过AMS跟zygote建立socket连接,发送消息后,zygote会判断当进程不存在时去孵化新的应用进程,然后再执行对应的ActivityThread.main()方法,重复的话有点多,涉及到的类和方法调用链也很多,梳理一遍对整个流程有一个更清晰的认识

启动流程的分析,有点感觉像是记流水账一样,类之间的方法相互调用,看几遍都不一定能记得住,我感觉也不需要记住,跟app应用层开发关联性不大
但是,必要的流程还是需要梳理清楚,知道进程之间的关系,加深对整个Android系统的认知,比如梳理完流程后,就能很清楚的认知app进程的孵化是需要zygote进程去调用native的fork,app进程的启动又是需要AMS进行发起,和zygote的通信是通过socket的方式发送消息,在AMS中有ActivityStarter类会判断进程是否存在,分发不同的逻辑,应用进程的启动会执行到ActivityThread.main()方法,不同的系统服务在SystemServer进程中初始化启动,并且有SystemServiceManager进行生命周期的管理等

如果感兴趣的朋友也可以跟我一样跟着系统源码一个方法一个方法的跟一下,加强自己吹逼的能力和知识储备

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容