app启动流程

作者: 學绘u | 来源:发表于2021-05-05 23:13 被阅读0次

Activity的创建,和生命周期的调用
Activity XML 布局文件的加载

1620216753(1).jpg

冷启动

当应用启动的时候,后台没有当前应用进程,这时系统会创建一个新的进程给应用。

热启动

当前应用已经打开,但被按下返回键或者home键不再显示在前台。当再次回到应用时为热启动

启动流程(冷启动)

  1. launcher进程开始,点击桌面图标,在ActivityManagerProxy类中通过binder方式发送startActivity到SystemServer进程中。
  2. SystemServer进程的里面管理了AMS,WMS,PMS等,当接收到startActivity后通过Socker方式后向Zygote进程中发送请求。
  3. Zygote进程通过fork创建APP进程。
  4. App进程的通过binder向SystemServer进程发起attachApplocation请求;(因为App进程开启后ActivityThread里面的main方法开始调用,main方法中通过activityThread.attach()里面会通过pid和uid等信息去绑定Application。)
  5. SystemServer进程收到请求后通过readStartActivityLocked调起ApplicationThreadProxy通过binder方式发送scheduleLaunchActivity请求。
  6. App进程的ApplictionThread收到信息后通过handler向主线程发送LAUNCH_ACTIVITY消息。
    7.主线程收到message后,通过发射机制创建目标Activity,并调用onCreate等方法

Application的创建

  1. ActivityThread里面的main函数开始
    ##ActivityThread
    public static void main(String[] args) {
        ...
        Looper.prepareMainLooper();
        long startSeq = 0;
        if (args != null) {
            ...
            // 1 通过ActivityThread.attach,具体看attach方法
            ActivityThread thread = new ActivityThread();
            thread.attach(false, startSeq);
            ...
            Looper.loop();
         }
    }
  1. attach方法通过aidl得到AMS的本地代理对象IActivityManager.attachApplication连接Application,
##ActivityThread
private void attach(boolean system, long startSeq) {
     ...
     if (!system) {
          final IActivityManager mgr = ActivityManager.getService();
          try {
              mgr.attachApplication(mAppThread, startSeq);
          } catch (RemoteException ex) {
              throw ex.rethrowFromSystemServer();
          }
       }else{
       ...
       } 
       ...
  1. AMS里面的attachApplication把pid和uid等传入到attachApplicationLocked方法中
##ActivityManagerService
public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            //获取pid
            int callingPid = Binder.getCallingPid();
            //获取uid
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            // 连接application
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }
  1. attachApplicationLocked中的ProcessRecord是进程记录类
    ,可以保存当前进程相关的一些信息(如pid,uip,Applicationinfo等)。thread.bindApplication准备绑定Application。
##ActivityManagerService
private final boolean attachApplicationLocked(IApplicationThread thread,
                                                  int pid, int callingUid, long startSeq) {
        ProcessRecord app;  //1
        long startTime = SystemClock.uptimeMillis();
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);  //2
            }
        } 
        ...
        if (app.instr != null) {  //当前进程是否正在活动
           thread.bindApplication(processName, appInfo, providers, app.instr.mClass,
                    profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection,
                    testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()),
                    app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial, isAutofillCompatEnabled);   //3
        } else {
            //Application 绑定到当前线程
            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, isAutofillCompatEnabled);  //4
        }
        ...
        //检测最可见的Activity是否在运行进程中等待,如果再则创建Activity
        if (mStackSupervisor.attachApplicationLocked(app)) {  //5
            didSomething = true;
        }
        ...
}
##ActivityThread.ApplicationThread
public final void bindApplication(String processName...boolean autofillCompatibilityEnabled) {
        ...
        setCoreSettings(coreSettings);
        AppBindData data = new AppBindData();
        data.processName = processName;  //当前进程名字
        data.appInfo = appInfo;     //app信息
        data.providers = providers; //providers
        ...
        //最后使用Handler发送消息,并携带AppBindData数据
        sendMessage(H.BIND_APPLICATION, data);
}
  1. ActivityThread的handleMessage接收sendMessage消息准备开始绑定application。
##ActivityThread.H
public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            case BIND_APPLICATION:
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                AppBindData data = (AppBindData) msg.obj;
                //开始绑定application
                handleBindApplication(data);  
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
            ...
        }
        ...
}
  1. ActivityThread里面的handleBindApplication正式绑定application
##ActivityThread 
private void handleBindApplication(AppBindData data) {
        ...
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);  //1
        ...
        Application app;
        ...
        //创建Application
        app = data.info.makeApplication(data.restrictedBackupMode, null);  //2
        ...
        //调用Application中的onCreate方法
        mInstrumentation.callApplicationOnCreate(app);  //3
        ...
}

##Instrumentation
public void callApplicationOnCreate(Application app) {
        app.onCreate();
}

总结

Activity的创建首先从ActivityThread的main函数开始,通过AMS根绝pid和uid去创建Application。

Activity的创建(未完待续...)

=======================================
1 xml在onCreate里面加载,在onResume里面绘制
2 pid进程id,uid用户id
3ActivityRecord

Activity的几种状态

1 运行状态,一个新Activity启动入栈后显示在屏幕前端,处于栈顶,可与用户交互的状态,也叫激活状态。
2 暂停状态,Activity失去焦点,被一个非全屏的Activity或透明的Activity放置在栈顶,此时的状态叫暂停状态。他依旧与窗口管理器保持连接,Activity依旧保持活力,但系统内存极端底下的时候会被强制终止。它仍然可见,但已经失去了焦点不可与用户进行交互。
3 停止状态,一个Activity被另外的Activity完全覆盖掉,它依旧保持所有状态和成员信息,但是它不再可见。此状态要保存当前数据和当前状态,否则一旦Activity退出或关闭时,当前UI状态就被丢失了,注意系统内存不够时Activity会被强制终止掉。
4 销毁状态,Activity被杀掉以后或被启动以前,此时activity已经不再栈内,需要重新启动才能显示和使用。

相关文章

网友评论

    本文标题:app启动流程

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