Android App启动(下文)

作者: 圣明 | 来源:发表于2021-12-02 20:25 被阅读0次

    ps:Android 27
    本文从ActivityThread#main开始,一只到Application创建结束

    首先是发生在ActivityThread内的

    我们先来看下入口main函数

    ActivityThread.main

    public static void main(String[] args) {
            ...
            Looper.prepareMainLooper();
    
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
            ...
            Looper.loop();
        }
    
    • 创建主线程looper
    • 创新主线程ActivityThread
    • Looper开启消息循环

    ActivityThread 重要成员

    # 负责进程间通信的IApplicationThread.stub对象
    final ApplicationThread mAppThread = new ApplicationThread();
    private class ApplicationThread extends IApplicationThread.Stub {
     ...
    }
    
    # 负责主线程消息分发的消息Handler
    final H mH = new H();
    private class H extends Handler {
     ...
    }
    

    IApplicationThread.java

    ActivityThread. attach

    // 不是系统进程,所以system是false
    private void attach(boolean system) {
            ...
            if (!system) {
               ...
                // 获取系统 AMS
                final IActivityManager mgr = ActivityManager.getService();
                try {
                    // attach mAppThread ( IApplicationThread.stub) to ams
                    mgr.attachApplication(mAppThread);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
               ...
            } 
            ...
        }
    

    现在我们转到AMS

    Ams也是一个Stub类,实现了IActivityManager.stub 接口,为了跨进程通信,我们来看看AmsattachApplication方法做了哪些

    ActivityManagerService.attachApplication

    public final void attachApplication(IApplicationThread thread) {
            synchronized (this) {
                int callingPid = Binder.getCallingPid();
                final long origId = Binder.clearCallingIdentity();
                attachApplicationLocked(thread, callingPid);
                Binder.restoreCallingIdentity(origId);
            }
        }
    

    ActivityManagerService.attachApplicationLocked

    两件事:

    • 通知ActivityThread 创建Application
    • 尝试启动第一个Activity,最终也是通知ActivityThread.ApplicationThread#scheduleLaunchActivity处理的
    private final boolean attachApplicationLocked(IApplicationThread thread,int pid){
            // 找到已经创建的Application record
            ProcessRecord app;
            long startTime = SystemClock.uptimeMillis();
            if (pid != MY_PID && pid >= 0) {
                synchronized (mPidsSelfLocked) {
                    app = mPidsSelfLocked.get(pid);
                }
            } else {
                app = null;
            }
            ...
           // 调回 ActivityThread
          if (app.instr != null) {
               thread.bindApplication(...)
          }
          ...
          if (normalMode) {
                try {
                    // 尝试启动第一个Activity
                    if (mStackSupervisor.attachApplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                    badApp = true;
                }
          }
    }
    

    然后再转到ActivityThread内查看ApplicationThread

    ActivityThread.ApplicationThread#bindApplication

    public final void bindApplication(xxxx) {
          ...
          // 往主线程发送一个BIND_APPLICATION的消息
          sendMessage(H.BIND_APPLICATION, data);
    }
    

    ActivityThread.H#handleMessage(Message msg)

    public void handleMessage(Message msg) {
           switch (msg.what) {
               case BIND_APPLICATION:
                   AppBindData data = (AppBindData)msg.obj;
                   handleBindApplication(data);
                   break;
          }
    }
    

    ActivityThread#handleBindApplication

    private void handleBindApplication(AppBindData data){
            Application app;
            try {
                ....
                // 创建Application对象
                app = data.info.makeApplication(data.restrictedBackupMode, null);
                ...
                try {
                    // 执行application的onCreate()
                    mInstrumentation.callApplicationOnCreate(app);
                } catch (Exception e) {
                    ..
                }
            } 
    }
    

    LoadedApk#makeApplication

    public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
            ...
            Application app = null;
            // 获取Application的全路径
            String appClass = mApplicationInfo.className;
            if (forceDefaultAppClass || (appClass == null)) {
                // 没取到自定义的就是要默认的
                appClass = "android.app.Application";
            }
    
            try {
                java.lang.ClassLoader cl = getClassLoader();
                // 创建一个baseContext,application中attachBaseContext的就是这个baseContext
                ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
                // 调用mInstrumentation的newApplication创建Application
                app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
                appContext.setOuterContext(app);
            } catch (Exception e) {
                ...
            }
            ...
            return app;
        }
    

    内部是反射创建,就不对贴代码了

    // Instrumentation#newApplication
    static public Application newApplication(Class<?> clazz, Context context)
                throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException {
            Application app = (Application)clazz.newInstance();
            app.attach(context);
            return app;
    }
    // Application#attach
    final void attach(Context context) {
            // 这里就是开始创建的baseContext,所以在Application的attachBaseContext内调用getApplicationContext会返回空
            attachBaseContext(context);
            mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
    

    然后会处理启动第一个Activity的消息去启动第一个Activity。

    相关文章

      网友评论

        本文标题:Android App启动(下文)

        本文链接:https://www.haomeiwen.com/subject/xipsxrtx.html