android代码启动流程2

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android代码启动流程2相关的知识,希望对你有一定的参考价值。

上回 说到,开始调用 ZygoteInit  main 函数,main 函数:

  • registerZygoteServer:注册一个 zygote server socket,所有来自客户端的连接都通过 socket 方式连接;
  • preload:预加载系统的类库和资源,这样其他程序启动将不再加载系统资源,只需加载自己程序的资源,这样就达到系统资源在程序之间共享;
  • startSystemServer:
技术分享
 private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
        /* Hardcoded command line to start the system server */
     //命令行参数,包括:uid,gid,group,process_name,process class
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
            "--capabilities=130104352,130104352",
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
       //解析命令行参数
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
       //从 zygote 进程派生一个新的进程,fork 可参考:http://linux.die.net/man/2/fork ,不同的是该进程结束时,也会让 zygote 进程结束
      //所以这里,会返回2次,一次返回的是 zygote 进程的 pid ,值大于0;一次返回的是子进程 pid,值等于0
            // fork 返回在 zygote 进程返回的子进程 pid,非0,在子进程中返回0
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
    //zygote 进程 pid 非0,直接返回,而子进程 pid = 0,对子进程进行设置
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }
技术分享

而 handleSystemServerProcess 将启动 com.android.server.SystemServer:

技术分享
private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        //因为有 zygote 监听 socket,所以 system server 不监听 socket 连接,此处关闭 
        closeServerSocket();

        // set umask to 0077 so new files and directories will default to owner-only permissions.
        FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO);
     
     //设置进程名字,即从命令行参数获取的:system_server 
        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }

        if (parsedArgs.invokeWith != null) {
            WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    null, parsedArgs.remainingArgs);
        } else {
            /*
             * Pass the remaining arguments to SystemServer.
             */
       /* zygoteInit -> applicationInit:设置 sdktarget 版本 -> invokeStaticMain:得到 com.android.server.SystemServer main 方法 -> ZygoteInit.MethodAndArgsCaller
        * ZygoteInit.MethodAndArgsCaller 方法抛出异常 MethodAndArgsCaller,跳过了在 startSystemServer 下面的代码:
             * if (ZYGOTE_FORK_MODE) {
        *     runForkMode();
        *   } else {
        *     runSelectLoopMode();
        *   }
        */
       RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs); } /* should never reach here */
     }
技术分享

 在对 MethodAndArgsCaller 异常 catch 语句里,直接调用了 com.android.server.SystemServer main 方法,而 zygote 进程因为 pid 不为0,执行 runSelectLoopMode 方法:

技术分享
 private static void runSelectLoopMode() throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList();
        ArrayList<ZygoteConnection> peers = new ArrayList();
        FileDescriptor[] fdArray = new FileDescriptor[4];

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        int loopCount = GC_LOOP_COUNT;
     //一直循环
        while (true) {
            int index;

            /*
             * Call gc() before we block in select().
             * It‘s work that has to be done anyway, and it‘s better
             * to avoid making every child do it.  It will also
             * madvise() any free memory as a side-effect.
             *
             * Don‘t call it every time, because walking the entire
             * heap is a lot of overhead to free a few hundred bytes.
             */
            if (loopCount <= 0) {
                gc();
                loopCount = GC_LOOP_COUNT;
            } else {
                loopCount--;
            }

       //采用非阻塞方式,等待并取出 zygote 连接
            try {
                fdArray = fds.toArray(fdArray);
                index = selectReadable(fdArray);
            } catch (IOException ex) {
                throw new RuntimeException("Error in select()", ex);
            }
            
            //selectReadable 返回值小于0 ,有错误发生;值等于0,有新的连接,加到 list 中;值大于0,处理当前连接
            if (index < 0) {
                throw new RuntimeException("Error in select()");
            } else if (index == 0) {
                ZygoteConnection newPeer = acceptCommandPeer();
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                boolean done;
                done = peers.get(index).runOnce();

                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }
    }
技术分享

 在 zygote 进程等待连接的同时,com.android.server.SystemServer 已经启动:

技术分享
    native public static void init1(String[] args);

    public static void main(String[] args) {
     ...
     //加载 jni ,init1 是本地方法
        System.loadLibrary("android_servers");
     // init1 -> frameworks/base/services/jni/com_android_server_SystemServer.cpp :: android_server_SystemServer_init1 -> 
    //          frameworks/base/cmds/system_server/library/system_init.cpp :: system_init
        init1(args);
    }

   // init1 将回调 init2 方法
    public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }
技术分享

init1 方法最终调用的是 system_init 方法(代码:frameworks/base/cmds/system_server/library/system_init.cpp)

技术分享
extern "C" status_t system_init()
{
    LOGI("Entered system_init()");

    sp<ProcessState> proc(ProcessState::self());
  
    sp<IServiceManager> sm = defaultServiceManager();
    LOGI("ServiceManager: %p\n", sm.get());

    sp<GrimReaper> grim = new GrimReaper();
    sm->asBinder()->linkToDeath(grim, grim.get(), 0);
  
   //初始化 SurfaceFlinger 和传感器
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsurfaceflinger", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the SurfaceFlinger
        SurfaceFlinger::instantiate();
    }

    property_get("system_init.startsensorservice", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the sensor service
        SensorService::instantiate();
    }

    // And now start the Android runtime.  We have to do this bit
    // of nastiness because the Android runtime initialization requires
    // some of the core system services to already be started.
    // All other servers should just start the Android runtime at
    // the beginning of their processes‘s main(), before calling
    // the init function.
    LOGI("System server: starting Android runtime.\n");
    AndroidRuntime* runtime = AndroidRuntime::getRuntime();
  
   //回调 com.android.server.SystemServer init2 方法
    LOGI("System server: starting Android services.\n");
    JNIEnv* env = runtime->getJNIEnv();
    if (env == NULL) {
        return UNKNOWN_ERROR;
    }
    jclass clazz = env->FindClass("com/android/server/SystemServer");
    if (clazz == NULL) {
        return UNKNOWN_ERROR;
    }
    jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
    if (methodId == NULL) {
        return UNKNOWN_ERROR;
    }
    env->CallStaticVoidMethod(clazz, methodId);
  
  //启动线程池,为 binder 服务
    LOGI("System server: entering thread pool.\n");
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    LOGI("System server: exiting thread pool.\n");

    return NO_ERROR;
}
技术分享

 init2 启动 ServerThread 线程,它会启动 android 系统所有的服务:

技术分享
 public void run() {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
            SystemClock.uptimeMillis());
    
        Looper.prepare();

        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);

        BinderInternal.disableBackgroundScheduling(true);
        android.os.Process.setCanSelfBackground(false);

        String factoryTestStr = SystemProperties.get("ro.factorytest");
        int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
                : Integer.parseInt(factoryTestStr);
      
     //初始化服务,如:网络服务,Wifi服务,蓝牙,电源,等等,初始化完成以后,加到 ServiceManager 中,
       //所以我们用 Context.getSystemService (String name) 才获取到相应的服务
        LightsService lights = null;
        PowerManagerService power = null;
        BatteryService battery = null;
        AlarmManagerService alarm = null;
        NetworkManagementService networkManagement = null;
        NetworkStatsService networkStats = null;
        NetworkPolicyManagerService networkPolicy = null;
        ConnectivityService connectivity = null;
        WifiP2pService wifiP2p = null;
        WifiService wifi = null;
        IPackageManager pm = null;
        Context context = null;
        WindowManagerService wm = null;
        BluetoothService bluetooth = null;
        BluetoothA2dpService bluetoothA2dp = null;
        DockObserver dock = null;
        UsbService usb = null;
        UiModeManagerService uiMode = null;
        RecognitionManagerService recognition = null;
        ThrottleService throttle = null;
        NetworkTimeUpdateService networkTimeUpdater = null;

        // Critical services...
        try {
            Slog.i(TAG, "Entropy Service");
            ServiceManager.addService("entropy", new EntropyService());

            Slog.i(TAG, "Package Manager");
            // Only run "core" apps if we‘re encrypting the device.

            ......
      
      //ActivityManagerService 是 android 系统最核心的服务之一 

//1.系统 context 的初始化,设置默认主题 android.R.style.Theme_Holo
//2.设置进程名字为 system_process
//3.初始化 ActivityStack

context = ActivityManagerService.main(factoryTest);

 

//往 service manager 里面添加一些服务,如:activity,meminfo,cupinfo,permission
ActivityManagerService.setSystemProcess();

 

//安装系统 content provider
Slog.i(TAG, "System Content Providers");
ActivityManagerService.installSystemProviders();

 

//设置 windows manager

ActivityManagerService.self().setWindowManager(wm);                    

            ......

        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
     
     //代码到这里,表明系统已经就绪,可以运行第3方代码
        ActivityManagerService.self().systemReady(new Runnable() {
            public void run() {
                Slog.i(TAG, "Making services ready");
         // systemui 是 3.0 以后添加的,因为没有物理键,提供虚拟键 
                startSystemUi(contextF);

          //诸多服务开始启动
                try {
                    if (batteryF != null) batteryF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Battery Service ready", e);
                }
                try {
                    if (networkManagementF != null) networkManagementF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Managment Service ready", e);
                }
                ......
            }
        });

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }

        Looper.loop();
        Slog.d(TAG, "System ServerThread is exiting!");
    }
技术分享

 而要执行 ActivityManagerService.self().systemReady(new Runnable() ...) 参数里面 Runnable 的 run 方法,还必须等到 ActivityManagerService systemReady:

技术分享
public void systemReady(final Runnable goingCallback) {
        synchronized(this) {
        //mSystemReady = false
            if (mSystemReady) {
                if (goingCallback != null) goingCallback.run();
                return;
            }
            
            // Check to see if there are any update receivers to run.
            if (!mDidUpdate) {
                if (mWaitingUpdate) {
                    return;
                }
         //检测是否有 ACTION_PRE_BOOT_COMPLETED register,该广播在 ACTION_BOOT_COMPLETED 前发出
                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
                List<ResolveInfo> ris = null;
                try {
                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
                                intent, null, 0);
                } catch (RemoteException e) {
                }
                if (ris != null) {
                    for (int i=ris.size()-1; i>=0; i--) {
              //检测广播注册是否是系统程序
                        if ((ris.get(i).activityInfo.applicationInfo.flags
                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
                            ris.remove(i);
                        }
                    }
                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
                    
                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
                    
                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
                    for (int i=0; i<ris.size(); i++) {
                        ActivityInfo ai = ris.get(i).activityInfo;
                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
                        if (lastDoneReceivers.contains(comp)) {
                            ris.remove(i);
                            i--;
                        }
                    }

                    for (int i=0; i<ris.size(); i++) {
                        ActivityInfo ai = ris.get(i).activityInfo;
                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
                        doneReceivers.add(comp);
                        intent.setComponent(comp);
                        IIntentReceiver finisher = null;
                        if (i == ris.size()-1) {
                            finisher = new IIntentReceiver.Stub() {
                                public void performReceive(Intent intent, int resultCode,
                                        String data, Bundle extras, boolean ordered,
                                        boolean sticky) {
                                    // The raw IIntentReceiver interface is called
                                    // with the AM lock held, so redispatch to
                                    // execute our code without the lock.
                                    mHandler.post(new Runnable() {
                                        public void run() {
                                            synchronized (ActivityManagerService.this) {
                                                mDidUpdate = true;
                                            }
                                            writeLastDonePreBootReceivers(doneReceivers);
                                            showBootMessage(mContext.getText(
                                                    R.string.android_upgrading_complete),
                                                    false);
                          //如果有 ACTION_PRE_BOOT_COMPLETED,在处理完广播 receive 以后 ,还会再次走 systemRead(goingCallback)
                                            systemReady(goingCallback);
                                        }
                                    });
                                }
                            };
                        }
                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
                        broadcastIntentLocked(null, null, intent, null, finisher,
                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
                        if (finisher != null) {
                            mWaitingUpdate = true;
                        }
                    }
                }
                if (mWaitingUpdate) {
                    return;
                }
                mDidUpdate = true;
            }
            
            mSystemReady = true;
        //mStartRunning 已经在 ActivityManagerService.main(int factoryTest) 设置成 true
            if (!mStartRunning) {
                return;
            }
        }

        
     ......

        retrieveSettings();
      
  
      //开始执行 runnable 的 run 方法,执行完成以后,系统就绪
        if (goingCallback != null) goingCallback.run();
        
        synchronized (this) {
            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
                try {
                    List apps = AppGlobals.getPackageManager().
                        getPersistentApplications(STOCK_PM_FLAGS);
                    if (apps != null) {
                        int N = apps.size();
                        int i;
                        for (i=0; i<N; i++) {
                            ApplicationInfo info
                                = (ApplicationInfo)apps.get(i);
                            if (info != null &&
                                    !info.packageName.equals("android")) {
                                addAppLocked(info);
                            }
                        }
                    }
                } catch (RemoteException ex) {
                    // pm is in same process, this will never happen.
                }
            }

            // Start up initial activity.
            mBooting = true;
            
            try {
                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
                    Message msg = Message.obtain();
                    msg.what = SHOW_UID_ERROR_MSG;
                    mHandler.sendMessage(msg);
                }
            } catch (RemoteException e) {
            }
       
        //恢复 top activity,因为现在没有任何启动的 activity, 将会启动 startHomeActivityLocked,启动 HOME  
            mMainStack.resumeTopActivityLocked(null);
        }
    }
技术分享

 HOME 启动以后,ActivityManagerService 中 finishBooting 方法会发出 Intent.ACTION_BOOT_COMPLETED 广播,调用该方法的地方有很多,resume activity 的时候或者出错的时候,

 调用一次以后就不再调用。

 

 至此 android 就完成了整个启动工作,整个流程可以用下图简洁表示:

技术分享







以上是关于android代码启动流程2的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段

Android小部件,启动一个片段?

Android - 应用程序启动时片段 onCreate 崩溃

android7.x Launcher3源代码解析---workspace和allapps载入流程

Android 7.0 Gallery图库源码分析2 - 分析启动流程