深入理解Activity进阶系列(一):Activity启动

来源:互联网 发布:白金数据txt 编辑:程序博客网 时间:2024/06/05 19:39

深入理解Activity进阶系列(一):Activity启动

本系列主要讲解Activity的一些进阶知识,大部分是通过源码分析了解Activity有关的内容,同时也会介绍一些平时比较不容易注意到的细节。

1. 深入理解Activity进阶系列(一):Activity启动

2. 深入理解Activity进阶系列(二):界面创建
……

本文主要讲解Activity启动过程,通过源码分比析较直观的展示了启动过程中具体做了什么事,并可以从中窥探Framewokr层几个重要的对象。

启动流程


Activity

从Activity的 public void startActivity(Intent intent) 入手分析,startActivity调用startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options)。startActivityForResult主要通过调用mInstrumentation的execStartActivity,执行启动操作。

这里稍微介绍一下mInstrumentation,是一个Instrumentation对象。

Instrumentation是执行application instrumentation代码的基类。当应用程序运行的时候instrumentation处于开启,Instrumentation将在任何应用程序运行前初始化,可以通过它监测系统与应用程序之间的交互。
Instrumentation似乎有些类似与window中的“钩子(Hook)函数”,在系统与应用程序之间安装了个“窃听器”。
一些插件化框架也是通过Instrumentation hook。

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,            @Nullable Bundle options) {// mParent顾名思义是当前Activity的父Activit,比如在使用//TabActivity会赋值。官方推荐使用Fragment,所以此处直接分析mParent == null的情况即可                if (mParent == null) {            options = transferSpringboardActivityOptions(options);            // 调用mInstrumentation.execStartActivity执行启动操作            Instrumentation.ActivityResult ar =                mInstrumentation.execStartActivity(                    this, mMainThread.getApplicationThread(), mToken, this,                    intent, requestCode, options);            if (ar != null) {                mMainThread.sendActivityResult(                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),                    ar.getResultData());            }            if (requestCode >= 0) {                mStartedActivity = true;            }            cancelInputsAndStartExitTransition(options);        } else {            // 忽略            if (options != null) {                mParent.startActivityFromChild(this, intent, requestCode, options);            } else {                mParent.startActivityFromChild(this, intent, requestCode);            }        }    }

Instrumentation的execStartActivity主要就是调用ActivityManagerNative.getDefault()的startActivityAsUser执行启动,那ActivityManagerNative和getDefault()具体是什么呢?

public abstract class ActivityManagerNative extends Binder implements IActivityManager
public interface IActivityManager extends IInterface
从中可以看出ActivityManagerNative是一个Binder类,Activity的启动已经通过Binder调用转交到系统服务中了。
IActivityManager Binder具体实现是ActivityManagerService,最终调用到ActivityManagerService的startActivityAsUser
调用进入ActivityManagerService的进程

Instrumentation

public ActivityResult execStartActivity(        Context who, IBinder contextThread, IBinder token, String target,        Intent intent, int requestCode, Bundle options) {        IApplicationThread whoThread = (IApplicationThread) contextThread;        ... // 监控该Intent是否在启动,命中返回        try {            intent.migrateExtraStreamToClipData();            intent.prepareToLeaveProcess(who);            // 调用ActivityManagerNative.getDefault()                .startActivityAsUser 启动Activity            int result = ActivityManagerNative.getDefault()                .startActivity(whoThread, who.getBasePackageName(), intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        token, target, requestCode, 0, null, options);            // 检查启动Activity是否合法,比如Activity是否在AndroidManifest注册            checkStartActivityResult(result, intent);        } catch (RemoteException e) {            throw new RuntimeException("Failure from system", e);        }        return null;    }

ActivityManagerService

ActivityManagerService的startActivityAsUser方法又调用了mStackSupervisor的 startActivityMayWait,mStackSupervisor是一个StackSupervisor对象。

ActivityStackSupervisor管理Activity栈
每一个ActivityRecord都会有一个Activity与之对应,一个Activity可能会有多个ActivityRecord,因为Activity可以被多次实例化,取决于其launchmode。一系列相关的ActivityRecord组成了一个TaskRecord,TaskRecord是存在于ActivityStack中,ActivityStackSupervisor是用来管理这些ActivityStack的。

@Override    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {        ...        // 调用mStackSupervisor.startActivityMayWait        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,                profilerInfo, null, null, options, false, userId, null, null);    }

ActivityStackSupervisor

执行到ActivityStackSupervisor的时候,在startActivityMayWait中进行了一系列的方法调用,最终调用ActivityStack的resumeTopActivityLocked方法

ActivityStack

每一个ActivityRecord都会有一个Activity与之对应,一个Activity可能会有多个ActivityRecord,因为Activity可以被多次实例化,取决于其launchmode。一系列相关的ActivityRecord组成了一个TaskRecord,TaskRecord是存在于ActivityStack中,ActivityStackSupervisor是用来管理这些ActivityStack的。

  • 调用ActivityStackSupervisor的startActivityMayWait
  • startActivityMayWait调用startActivityLocked
  • startActivityLocked调用startActivityUncheckedLocked
  • startActivityUncheckedLocked调用resumeTopActivitiesLocked
  • resumeTopActivitiesLocked调用ActivityStack的resumeTopActivityLocked

ActivityStack

ActivityStack的resumeTopActivityLocked又调用回ActivityStackSupervisor中的startSpecificActivityLocked

ActivityStackSupervisor

ActivityStackSupervisor的startSpecificActivityLocked调用了realStartActivityLocked,而 realStartActivityLocked最终调用了app.thread.scheduleLaunchActivity

IApplicationThread thread;
public interface IApplicationThread extends IInterface
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
ApplicationThreadNative的具体实现是ActivityThread中的ApplicationThread
ApplicationThread实现了许多Activity和Service 启动、暂停等有关的操作
调用进入应用程序的进程

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,            boolean andResume, boolean checkConfig) throws RemoteException {            ...            // 调用了app.thread.scheduleLaunchActivity            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);            ...        return true;    }

ApplicationThread

ApplicationThread的scheduleLaunchActivity通过mH发送了一条H.LAUNCH_ACTIVITY消息,mH是一个H对象,H是一个Handle。

final H mH = new H();
private class H extends Handler
H是一个Handler,封装了一些对Activity、Service等的处理消息具体操作

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,                int procState, Bundle state, PersistableBundle persistentState,                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {            ... // 更新一些状态和信息            // 发送LAUNCH_ACTIVITY消息            sendMessage(H.LAUNCH_ACTIVITY, r);        }
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {        Message msg = Message.obtain();        msg.what = what;        msg.obj = obj;        msg.arg1 = arg1;        msg.arg2 = arg2;        if (async) {            msg.setAsynchronous(true);        }        mH.sendMessage(msg);    }

mH收到LAUNCH_ACTIVITY消息时调用handleLaunchActivity

case LAUNCH_ACTIVITY: {                    // 调用ActivityThread的handleLaunchActivity                    handleLaunchActivity(r, null);                } break;

handleLaunchActivity先通过performLaunchActivity创建相应的Activity,如果调用handleResumeActivity设置相关的界面等

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {        ...        // 1.调用ActivityThread的performLaunchActivity        Activity a = performLaunchActivity(r, customIntent);        if (a != null) {            ...            // 2.调用ActivityThread的handleResumeActivity            handleResumeActivity(r.token, false, r.isForward,                    !r.activity.mFinished && !r.startsNotResumed);           ...        } else {            ...        }    }

ActivityThread的performLaunchActivity做了许多事情,可以说是Activity启动流程最主要的一步了, 具体内容见代码注释。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){        Activity activity = null;        try {        // 获取类加载器            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();             // 调用Instrumentation的newActivity 实例化Activity            activity = mInstrumentation.newActivity(                    cl, component.getClassName(), r.intent);              ...        } catch (Exception e) {        }        try {        // 调用LoadedApk的makeApplication获取Application,        //如果没有则创建,创建Application会创建一个ContextImpl,并赋值给Application的mBase,        //创建成功调用Application,具体下面会分析            Application app = r.packageInfo.makeApplication(false, mInstrumentation);             if (activity != null) {            // 调用了ContextImpl.createActivityContext 创建了ContextImpl的实例             Context appContext = createBaseContextForActivity(r, activity);                // 调用Activity的attach,将之前的创建的ContextImpl实例赋值给Activity的mBase,               // 以及Window的创建和界面的加载,具体之后(第二篇)会详细分析               // 注意此时才将mBase赋值,之前Activity已经实例化,但mBase还未赋值                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);               ...                if (r.isPersistable()) { // callActivityOnCreate会调用Activity的performCreate, // Activity的postPerformCreate会调用Activity的onCreate方法                   mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);                } else {                    mInstrumentation.callActivityOnCreate(activity, r.state);                }                if (!r.activity.mFinished) {                 // 调用Activity的performStart方法,之后会执行Activity的onStart()方法                    activity.performStart();                    r.stopped = false;                }              ...            }            //     final ArrayMap<IBinder, ActivityClientRecord> mActivities =             // new ArrayMap<>();            mActivities.put(r.token, r);         }        return activity;    }

尝试创建Application是通过packageInfo创建的,packageInfo是一个LoadedApk。

LoadedApk
Local state maintained about a currently loaded .apk.

LoadedApk对象是APK文件在内存中的表示。 Apk文件的相关信息,诸如Apk文件的代码和资源,甚至代码里面的Activity,Service、Receiver等组件的信息我们都可以通过此对象获取。

Activity创建之后调用了ActivityThread的handleResumeActivity,之后会调用Activity的onResume()方法。从这里可以大概看出Activity界面还没有显示出来的时候就调用了onResume方法,具体流程详见Activity启动流程源码分析(二):界面创建

总结


这里写图片描述

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 车被自行车刮了怎么办 刮花别人的车门怎么办 破腹产九个月意外怀孕怎么办 破腹产一年半意外怀孕怎么办 37天流产了该怎么办 旧鞋穿着磨脚了怎么办 皮鞋磨脚怎么办小窍门 拉链从下面开了怎么办 高帮足球鞋松了怎么办 橡筋裤头太紧了怎么办 内增高鞋跟太高怎么办 电脑增高架高了怎么办 银行取钱走后回来说少了怎么办 运动t桖太大了怎么办 袖口松紧太紧了怎么办 衣服穿着就皱了怎么办 麻料的衣服很皱怎么办 麻料衣服皱了怎么办 棉麻裤子皱了怎么办 裙子屁股坐皱了怎么办 真丝衣服洗皱了怎么办 粘纤的衣服皱了怎么办 硅胶手机壳粘灰怎么办 橡筋裤子买大了怎么办 橡筋裤子腰小了怎么办 地垫粘瓷砖上怎么办 汽车围裙锈透了怎么办 万能胶水沾到手上怎么办 圆领体恤领口容易皱怎么办 上衣剪了个洞怎么办 上衣破了个洞怎么办 鸟屎腐蚀车漆怎么办 毛风衣叠久了怎么办 黑色的衣服沾毛怎么办 雪纺裙子弄上油怎么办 内衣买小了怎么办妙招 长裤衬衫裙邹了怎么办 100棉衬衣皱了怎么办? 短袖t恤袖口大了怎么办 短袖底下卷边了怎么办 棉质短袖衫缩水怎么办