博客
关于我
【Android】源码分析 - Activity启动流程
阅读量:581 次
发布时间:2019-03-11

本文共 7422 字,大约阅读时间需要 24 分钟。

启动Activity的方式

Activity的启动方式主要有两种,一种是在Launcher界面点击应用图标,另一种是在应用中通过Intent进行跳转。以下将重点介绍后者,即通过Intent启动Activity的流程。

1.1 startActivity()

@Overridepublic void startActivity(Intent intent) {    this.startActivity(intent, null);}@Overridepublic void startActivity(Intent intent, @Nullable Bundle options) {    if (options != null) {        startActivityForResult(intent, -1, options);    } else {        startActivityForResult(intent, -1);    }}

1.2 startActivityForResult()

最终都会调用startActivityForResult()方法。我们跟进去看看:

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {    if (mParent == null) {        // 转交给Instrumentation来startActivity        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;        }        // ... 其他代码 ...    } else {        // ... 其他代码 ...    }    // ... }

1.3 execStartActivity()

继续进入Instrumentation类,看看execStartActivity方法:

// Instrumentation类public ActivityResult execStartActivity(        Context who, IBinder contextThread, IBinder token, Activity target,        Intent intent, int requestCode, Bundle options) {    IApplicationThread whoThread = (IApplicationThread) contextThread;    if (mActivityMonitors != null) {        synchronized (mSync) {            final int N = mActivityMonitors.size();            for (int i = 0; i < N; i++) {                final activitymonitor am = mActivityMonitors.get(i);                if (am.match(who, null, intent)) {                    am.mhits++;                    if (am.isblocking()) {                        return am.getResult() ?: null;                    }                }            }            break;        }    }    try {        intent.migrateExtraStreamToClipData();        intent.prepareToLeaveProcess();        // 交给ActivityManagerNative来startActivity        int result = ActivityManagerNative.getDefault()                .startActivity(whoThread, who.getBasePackageName(), intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        token, target != null ? target.mEmbeddedID : null,                        requestCode, 0, null, options);        // 检查启动Activity的结果        checkStartActivityResult(result, intent);    } catch (RemoteException e) {    }    return null;}

1.4 ActivityManagerNative是什么?

ActivityManagerNative是一个Binder对象,实现了IActivityManager接口。其getDefault()方法通过asInterface(IBinder obj)方法构建了ActivityManagerProxy单例。

public abstract class ActivityManagerNative extends Binder implements IActivityManager {    static public IActivityManager asInterface(IBinder obj) {        if (obj == null) {            return null;        }        IActivityManager in = (IActivityManager) obj.queryLocalInterface(descriptor);        if (in != null) {            return in;        }        return new ActivityManagerProxy(obj);    }    static public IActivityManager getDefault() {        return gDefault.get();    }    private static final Singleton
gDefault = new Singleton
() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };}

1.5 ActivityManagerService(AMS)

看AMS的startActivity()方法:

@Overridepublic final int startActivity(IApplicationThread caller, String callingPackage,        Intent intent, String resolvedType, IBinder resultTo, String resultWho,        int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) {    return startActivityAsUser(caller, callingPackage, intent, resolvedType,            resultTo, resultWho, requestCode, startFlags, profilerInfo, options,            UserHandle.getCallingUserId());}@Overridepublic 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) {    enforceNotIsolatedCaller("startActivity");    userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,            false, ALLOW_FULL_ONLY, "startActivity", null);    // TODO: Switch to user app stacks here.    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,            resolvedType, null, null, resultTo, resultWho, requestCode,            startFlags, profilerInfo, null, null, options, false, userId, null, null);}

可以看出,Activity启动任务被AMS转交给了ActivityStackSupervisor的startActivityMayWait方法。

1.6 ActivityStackSupervisor

ActivityStackSupervisor类中的startActivityMayWait方法调用startActivityLocked()继续执行,而startActivityLocked()方法中又会调用startActivityUncheckedLocked()方法:

final int startActivityMayWait(IApplicationThread caller, int callingUid,        String callingPackage, Intent intent, String resolvedType,        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,        IBinder resultTo, String resultWho, int requestCode, int startFlags,        ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,        Bundle options, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer,        TaskRecord inTask) {    // ... 省略一大片代码 ...    int res = startActivityLocked(caller, intent, resolvedType, aInfo,            voiceSession, voiceInteractor, resultTo, resultWho, requestCode,            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid,            startFlags, options, ignoreTargetSecurity, componentSpecified, null, container,            inTask);    // ... 再省略一大片代码 ...}

1.7 ActivityStack

跟进它的resumeTopActivityLocked()方法:

final boolean resumeTopActivityLocked(ActivityRecord prev) {    return resumeTopActivityLocked(prev, null);}final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {    if (mStackSupervisor.inResumeTopActivity) {        // Don't even start recursing.        return false;    }    boolean result = false;    try {        // Protect against recursion.        mStackSupervisor.inResumeTopActivity = true;        if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {            mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;            mService.updateSleepIfNeededLocked();        }        // 注意这里        result = resumeTopActivityInnerLocked(prev, options);    } finally {        mStackSupervisor.inResumeTopActivity = false;    }    return result;}

1.8 resumeTopActivityInnerLocked()

继续看看resumeTopActivityInnerLocked()方法:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {    // 看这里,又返回交给了ActivityStackSupervisor类    mStackSupervisor.startSpecificActivityLocked(next, true, false);    // ... 省略一大片代码 ...}

通过上述步骤,我们可以清晰地看到,从用户触发startActivity()到最终由ActivityManagerService(AMS)通过ActivityStackSupervisor启动Activity的整个流程。

转载地址:http://kcvtz.baihongyu.com/

你可能感兴趣的文章
Django ORM操作
查看>>
京喜小程序体验评分优化实践
查看>>
C#中文转换成拼音
查看>>
C++错误笔记
查看>>
【无线通信模块】GPRS DTU不稳定和容易掉线原因
查看>>
SpringBoot使用RedisTemplate简单操作Redis的五种数据类型
查看>>
国标流媒体服务器以ROOT身份运行提示“permission denide”报错解决
查看>>
国标流媒体服务器在linux系统运行提示fork/exec ……/redis/redis-server错误解决方案
查看>>
国标GB28181协议视频推流平台EasyGBD在Linux下编译报“UINT64_C在此作用领域中尚未声明”错误
查看>>
qt中转到槽后如何取消信号与槽关联
查看>>
qt问题记录-spin box与double spin box
查看>>
移动端事件
查看>>
css 图片按比例缩放
查看>>
小程序form表单里面buton点击事件失效
查看>>
微信小程序placeholder设置自定义样式
查看>>
spring-day01
查看>>
spring的值注入与组件扫描
查看>>
C#跨窗体程序调用方法的具体操作
查看>>
C#中创建Android项目
查看>>
统计学之变异系数与是非标志
查看>>