Activity启动流程

Activity启动流程

Android应用程序框架层中的ActivityManagerService启动Activity的过程大致如下图所示:

在这里插入图片描述

下面简要介绍一下启动的过程:

​ Step 1. 无论是通过Launcher来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerService.startActivity接口;

​ Step 2. ActivityManagerService调用ActivityStack.startActivityMayWait来做准备要启动的Activity的相关信息;

​ Step 3. ActivityStack通知ApplicationThread要进行Activity启动调度了,这里的ApplicationThread代表的是调用ActivityManagerService.startActivity接口的进程,对于通过点击应用程序图标的情景来说,这个进程就是Launcher了,而对于通过在Activity内部调用startActivity的情景来说,这个进程就是这个Activity所在的进程了;1.一种是点击程序进入启动的活动 2.另一种而是在已有的活动中调用startActivity

​ Step 4. ApplicationThread不执行真正的启动操作,它通过调用ActivityManagerService.activityPaused接口进入到ActivityManagerService进程中,看看是否需要创建新的进程来启动Activity;

​ Step 5. 对于通过点击应用程序图标来启动Activity的情景来说,ActivityManagerService在这一步中,会调用startProcessLocked来创建一个新的进程,而对于通过在Activity内部调用startActivity来启动新的Activity来说,这一步是不需要执行的,因为新的Activity就在原来的Activity所在的进程中进行启动;

​ Step 6. ActivityManagerServic调用ApplicationThread.scheduleLaunchActivity接口,通知相应的进程执行启动Activity的操作;

​ Step 7. ApplicationThread把这个启动Activity的操作转发给ActivityThread,ActivityThread通过ClassLoader导入相应的Activity类,然后把它启动起来。

​ Step 8. 到了 ActivityThread.handleLaunchActivity 在现有的活动中进行创建

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       ...
        //在活动之前 创建
        //通过WindowManagerGlobal创建了WindowManager
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
            ...
    }

接下来调用了performLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        Activity activity = null;
        try { //Activity通过ClassLoader创建出来
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);  
        } ...
        try {
            //创建Application
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ...
            if (activity != null) {
                //创建Activity所需的Context
                Context appContext = createBaseContextForActivity(r, activity);
                ...
                //将Context与Activity进行绑定
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor);
                ...
                    //调用activity.oncreate
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                ...
                     //调用Activity的onstart方法
                     activity.performStart();
                           //调用activitu的OnRestoreInstanceState方法进行Window数据恢复 
             mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                ...
        return activity;
    }

通过ClassLoad 创建完毕Activity 创建活动所需要 的Application 和 Context

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
        //ContextImpl的绑定
        attachBaseContext(context);
        //在当前Activity创建Window
        mWindow = new PhoneWindow(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        ...
        //为Window设置WindowManager
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        //创建完后通过getWindowManager就可以得到WindowManager实例
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }

在通过actvity.attach(); 创建 Window ,并设置 Window 的WindowManager , 在setWindowManager 方法中 设置了WindowManagerImpl 。

在创建完毕 WindowManager 实例后,接着调用

mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 此时的onCreate 方法,就是Activity 的onCreate方法

public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
final void performCreate(Bundle icicle) {
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

同理 也调用了 activity.performStart();
调用activitu的OnRestoreInstanceState方法进行Window数据恢复
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState);

接着 handleLaunchActivity 代码往下理解,目前我们已经创建完毕Activity 并且 绑定Window。而接下来调用了handleResumeActivity方法

inal void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
    ...
    //执行到onResume方法
    ActivityClientRecord r = performResumeActivity(token, clearHide);
    if (r != null) {
        final Activity a = r.activity;
        boolean willBeVisible = !a.mStartedActivity;
        ...
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (a.mVisibleFromClient) {
                a.mWindowAdded = true;
                wm.addView(decor, l);
            }

        }
        ...
        if (!r.activity.mFinished && willBeVisible
                && r.activity.mDecor != null && !r.hideForNow) {
            ...
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                //视图显示
                r.activity.makeVisible(); 
            }
        }
        //resume完成
        if (reallyResume) {
              ActivityManagerNative.getDefault().activityResumed(token);
        }
    } else {
        ...
    }
}

方法中通过调用performResumeActivity来完成onResume生命周期的回调,makeVisible方法最终通过WMS服务操作View

void makeVisible() {
        if (!mWindowAdded) {
            //这里返回的ViewManager其实就是WindowManagerImpl [见3.3]
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }

ViewManager addView方法

public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        //mGlobal 进行管理
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }

WindowManagerGlobal.addView

public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        ......
        ViewRootImpl root;
        View panelParentView = null;
        ......
            //创建ViewRootImpl
            root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);

            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);

        try {
            //设置View
            root.setView(view, wparams, panelParentView);
        } catch (RuntimeException e) {
            synchronized (mLock) {
                final int index = findViewLocked(view, false);
                if (index >= 0) {
                    removeViewLocked(index, true);
                }
            }
            throw e;
        }
    }

WindowManagerGlobal类中几个重要的成员:

mViews:管理的所有View

mRoots:View所对应的ViewRootImpl

mParams:View所对应的LayoutParams

这三个成员变量都是大小始终保持相等的数组,这样有关联关系的View对象,ViewRoot和WindowManager.LayoutParams对象分别保存在数组mViews,mRoots,mParams的相同位置上

ViewRootImpl

public ViewRootImpl(Context context, Display display) {
    mContext = context;
    //获取IWindowSession的代理类 
    mWindowSession = WindowManagerGlobal.getWindowSession();
    mDisplay = display;
    mThread = Thread.currentThread(); //主线程
    mWindow = new W(this); 
    mChoreographer = Choreographer.getInstance
}

mWindowSession:WMS端的Session的代理 对象

mWindow:继承于IWindow.Stub的W对象

mChoreographer:绘制相关的对

WindowManagerGlobal.getWindowSession

public static IWindowSession getWindowSession() {
    synchronized (WindowManagerGlobal.class) {
        if (sWindowSession == null) {
            try {
                InputMethodManager imm = InputMethodManager.getInstance();
                //获取WMS的代理类
                IWindowManager windowManager = getWindowManagerService();
                //经过Binder调用
                sWindowSession = windowManager.openSession(
                        new IWindowSessionCallback.Stub() {...},
                        imm.getClient(), imm.getInputContext());
            } catch (RemoteException e) {
                ...
            }
        }
        return sWindowSession
    }
}

addView 中 ViewRootImpl.setView()

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
  synchronized (this) {
    ...
    requestLayout();
    ...
    //通过Binder调用,进入system_server进程的Session
    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
          getHostVisibility(), mDisplay.getDisplayId(),
          mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
          mAttachInfo.mOutsets, mInputChannel);
    ...
  }
}

调用成员方法requestLayout来请求对应用程序的窗体视图的UI做第一次布局 调用ViewRoot类的成员变量mWindowSession所描述的一个类型为Session的Binder代理对象的成员函数add来请求WindowManagerService增加一个WindowState对象,以便可以用来描述当前正在处理的一个ViewRoot所关联的一个应用程序窗口

此篇文章 部分内容来自 https://www.cnblogs.com/carlo/p/4947586.html
WMS 分析 https://blog.csdn.net/afu10086/article/details/80138154 感谢博主!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值