Android Framework实战视频--FallbackHome进程启动及Activity启动篇

Posted learnframework

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Framework实战视频--FallbackHome进程启动及Activity启动篇相关的知识,希望对你有一定的参考价值。

课程答疑和新课信息:QQ交流群:422901085进行课程讨论
FrameWork入门课视频链接:https://edu.csdn.net/course/detail/30298
FrameWork实战课1视频链接:https://edu.csdn.net/course/detail/30275
专题博客系列:
Android 8.1 zygote 启动过程源码
Android Framework实战视频–Zygote的fork进程篇
Android Framework实战视频–SystemServer启动篇
Android Framework实战视频–SystemServer启动FallbackHome篇
Android Framework实战视频–FallbackHome进程启动及Activity启动篇
Android Framework实战视频–FallbackHome结束启动Launcher篇

android Framework实战视频–FallbackHome进程启动及Activity启动篇

android 8.1 源码中FallbackHome进程启动及Activity启动分析

上一节课已经一步步分析到了Process.start了,那本节就是来分析Process的start方法具体是怎么一步步的把进程启动及进程启动后对应的Activity是怎么启动的

1 应用进程的创建

首先看Process.start的源码:

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 invokeWith,
                                  String[] zygoteArgs) {
        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }

这里调用了ZygoteProcess的start方法:

 public final Process.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 invokeWith,
                                                  String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }

这里调用到了startViaZygote方法:

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);
        }
    }

这里设置了一系列参数后,在调用zygoteSendArgsAndGetResult

 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();

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

            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            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这里就调用了BufferedWriter的writer对象进行了socket的写入数据,writer就是zygoteState.writer,
那zygoteState.writer又具体是怎么赋值的呢?

   public static ZygoteState connect(String socketAddress) throws IOException {
            DataInputStream zygoteInputStream = null;
            BufferedWriter zygoteWriter = null;
            final LocalSocket zygoteSocket = new LocalSocket();

            try {
            //连接zygote进程的serversocket
                zygoteSocket.connect(new LocalSocketAddress(socketAddress,
                        LocalSocketAddress.Namespace.RESERVED));
				//socket中的输入流
                zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());

				//socket中的输出流
                zygoteWriter = new BufferedWriter(new OutputStreamWriter(
                        zygoteSocket.getOutputStream()), 256);
            } catch (IOException ex) {
                try {
                    zygoteSocket.close();
                } catch (IOException ignore) {
                }

                throw ex;
            }

            String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
            Log.i("Zygote", "Process: zygote socket " + socketAddress + " opened, supported ABIS: "
                    + abiListString);

            return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
                    Arrays.asList(abiListString.split(",")));
        }

这里面的socketAddress是如下代码赋值的:

public static final ZygoteProcess zygoteProcess =
        new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);
public static final String ZYGOTE_SOCKET = "zygote";

也就是ZYGOTE_SOCKET变量,变量就是前几节课讲的zygote进程创建的Server名字
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中的main方法中:

  String socketName = "zygote";

所以就是这样ActivtiyManagerService通过socket与zygote进行一个跨进程通信。

在这里插入图片描述
ActivityManagerService这边把要创建一个进程的主要参数等需要准备好,然后发送给zygote端,zygote端接受到了发来数据后创建对应的进程。创建对应进程时候还会执行传过来的entryPoint即 "android.app.ActivityThread"类的main方法
接下来看看分析之前Zygote部分的接受和创建进程,前面zygote已经知道,zygote本身是一直循环执行runSelectLoop里面的While:

 Runnable runSelectLoop(String abiList) {
//省略; 

        while (true) {
  			 //省略; 
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }

                if (i == 0) {
                //如果是本身serverSocket的fd有输入消息,则保存住新建连接的客户端peer和fd,比如:第一次AMS就需要绑定
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    try {
                    //如果哪个peer或者fd有消息了,则processOneCommand读取里面消息
                        ZygoteConnection connection = peers.get(i);
                        final Runnable command = connection.processOneCommand(this);
                        if (mIsForkChild) {
                         //省略
                            return command;
                        } 
        }
    }

所以核心在processOneCommand方法:

 Runnable processOneCommand(ZygoteServer zygoteServer) {
        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
        //读取发送过来的参数
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } 
        //省略
        parsedArgs = new Arguments(args);
      //省略
      //根据参数创建对应的进程,这里本质和以前分析system server进程创建一样
        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) {
			 //省略
                return handleChildProc(parsedArgs, descriptors, childPipeFd);
            } 
            //省略
    }

这里processOneCommand创建好了进程后,又调用handleChildProc方法:
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd) {
//省略
//这里最后调用ZygoteInit.zygoteInit和以前systemserver其实是一样的,只不过这里的remainingArgs参数变成ActivityThread
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);

}

/这里最后调用ZygoteInit.zygoteInit和以前systemserver其实是一样的,只不过这里的remainingArgs参数变成ActivityThread类,返回的ActivityThread的main方法执行的Runable

2 应用进程的Activity启动

当应用进程被创建后,最开始就是执行的ActivityThread的main方法

 public static void main(String[] args) {
    //省略
        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();
		//创建ActivityThread对象,并且调用attach方法
        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");
    }

这里主要就是对loop进行初始化,接下来再创建ActivityThread对象,调用它的attach方法:

 private void attach(boolean system) {
        if (!system) {
           //省略
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
          //省略
        }
        //省略
    }

这里主要应用端会获取system server中的AMS对象IBinder对象,然后调用attachApplication(mAppThread)方法,这个attachApplication真正实现那是在ActivityManagerService:

 @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
         //省略
            attachApplicationLocked(thread, callingPid);
           //省略
        }
    }

这里又调用重载方法:private final boolean attachApplicationLocked(IApplicationThread thread,
int pid);

 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
		//省略
     			//跨进程调用,执行对应进程的Application的onCreate等方法
                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 (mStackSupervisor.attachApplicationLocked(app)) {

			//省略。。
        return true;
    }

这里调用StackSupervisor.attachApplicationLocked(app):

   boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
				//省略
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                  //省略
        return didSomething;
    }
这里又会调用到realStartActivityLocked方法:
    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,
     //省略

        return true;
    }

这里最后跨进程调回应用进程,ActivityThread的ApplicationThread的scheduleLaunchActivity方法,这个方法再进行Activtiy的onCreate等调用,这里就不带大家分析ActivityThread的相关内容了,因为ActivityThread中基本属于应用层自己执行代码,而且相对不那么复杂,自己完全可以分析,所以当作作业留给大家自己分析接下来的ActivityThread部分。
最后附上对应的流程总图:
在这里插入图片描述

以上是关于Android Framework实战视频--FallbackHome进程启动及Activity启动篇的主要内容,如果未能解决你的问题,请参考以下文章

Android Framework实战视频--FallbackHome结束启动Launcher篇

Android Framework实战视频--系统SystemServer启动篇

Android Framework实战视频--FallbackHome结束启动Launcher篇

Android Framework实战视频--SystemServer启动FallbackHome篇

Android Framework实战视频--BootAnimation的启动源码分析(Android8.1)

Android Framework实战视频系列