返回顶部
首页 > 资讯 > 移动开发 >Android Activity启动流程一:从Intent到Activity创建
  • 253
分享到

Android Activity启动流程一:从Intent到Activity创建

android面试javaactivity启动流程 2023-08-31 06:08:28 253人浏览 泡泡鱼
摘要

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、概览二、应用

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端移动开发人工智能等,希望大家多多支持。

目录

在这里插入图片描述

学习前,建议有相关知识储备:
【Android 基础】 应用(Application)启动流程

通过本文你可以学习到Activity启动流程。

一、概览

Activity 是 Android 四大组件之一,很有必要知道它的启动过程,我们在上一篇文章中介绍了 APP的启动流程,里面大概讲到了Activity的
启动流程,在本文中,我们系统的再总结一下,当成一个记录。

Activity 的启动方式我们讲有两种,一种是在应用内部启动,另一种是外部启动,比如Launcher;

  • 应用内启动
    通过 startActivity、startActivityForResult等方式来启动 Activity

其流程我们总结下:

调用 Activity 的 startActivity 方法来启动目标 Activity
2、接着就会调用到 Instrunmentation 的 execStartActivity 方法,然后调用到 AMS 的 startActivity 中去
3、调用到 AMS 中后,会执行到ActivityStarter 的 execute 方法,接着就会进行一些校验和判断权限,包括进程检查,intent检查,权限检查、是否启用新栈等
4、所有的信息存储在ActivityRecord中,ActivityRecord是Activity在system_server进程中的镜像,Activity实例与ActivityRecord实例一一对应。ActivityRecord用来存储Activity的信息,如所在的进程名称,应用的包名,所在的任务栈的taskAffinity等
5、中间再经过一系列调用,又回调到 ActivityThread 的 handleLaunchActivity 来启动 Activity。

借用一张网络图片
11

  • 应用外启动
    通过Launcher 进程启动,Launcher 就是我们桌面程序,当系统开机后, Launcher 也随之被启动。

fork并调用ActivityThread的main方法创建app进程
2、然后从 ActivityThread 调用到AMS中的attachApplicationLocked,创建Application
3、Application创建完后,调用ActivityStackSupervisor的attachApplicationLocked方法,最终调用到handleLaunchActivity,进行activity的创建

二、应用内启动源码流程 (startActivity)

我们就从源码出发,一起来看看startActivity后面的流程

2.1 startActivity()

Activity.java

    @Override    public void startActivity(Intent intent) {        this.startActivity(intent, null);    }        @Override    public void startActivity(Intent intent, @Nullable Bundle options) {        if (options != null) {            startActivityForResult(intent, -1, options);        } else {          startActivityForResult(intent, -1);        }    }        public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {        startActivityForResult(intent, requestCode, null);    }
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,            @Nullable Bundle options) {        if (mParent == null) {            options = transferspringboardActivityOptions(options);            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());            }        } else {            // 最终也是调用 execStartActivity 方法,源码如下            if (options != null) {                mParent.startActivityFromChild(this, intent, requestCode, options);            } else {                mParent.startActivityFromChild(this, intent, requestCode);            }        }    }
    public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,            int requestCode, @Nullable Bundle options) {        options = transferSpringboardActivityOptions(options);        Instrumentation.ActivityResult ar =            mInstrumentation.execStartActivity(                this, mMainThread.getApplicationThread(), mToken, child,                intent, requestCode, options);        if (ar != null) {            mMainThread.sendActivityResult(                mToken, child.mEmbeddedID, requestCode,                ar.getResultCode(), ar.getResultData());        }        cancelInputsAndStartExitTransition(options);    }

上面代码中,最终都会调用了 execStartActivity 方法,该方法会返回一个启动结果。我们一起来看看
frameworks/base/core/java/android/app/Instrumentation.java

        public ActivityResult execStartActivity(        Context who, IBinder contextThread, IBinder token, String target,        Intent intent, int requestCode, Bundle options) {                IApplicationThread whoThread = (IApplicationThread) contextThread;                try {            intent.migrateExtraStreamToClipData();            intent.prepareToLeaveProcess(who);        // 这里的service 就是 ActivityManagerService, 具体可以跟代码看到             // 这么一句 : ServiceManager.getService(Context.ACTIVITY_SERVICE);                        int result = ActivityManager.getService()                .startActivity(whoThread, who.getBasePackageName(), intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        token, target, requestCode, 0, null, options);            checkStartActivityResult(result, intent);        } catch (RemoteException e) {                    }        return null;    }

通过 Binder 调用 AMS 启动 Activity,我们接着往下看

2.2 startActivityAsUser()

ActivityManagerService.java

public class ActivityManagerService extends IActivityManager.Stub    @Override    public final int startActivity(IApplicationThread caller, String callingPackage,       Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,       int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {      return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,              resultWho, requestCode, startFlags, profilerInfo, bOptions,              UserHandle.getCallingUserId());    }    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,             boolean validateIncomingUser) {        enforceNotIsolatedCaller("startActivity");          // 首先 检查调用者权限        userId = MactivityStartController.checkTargetUser(userId, validateIncomingUser,                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");          // TODO: Switch to user app stacks here.        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")                .setCaller(caller)                .setCallingPackage(callingPackage)                .setResolvedType(resolvedType)                .setResultTo(resultTo)                .setResultWho(resultWho)                .setRequestCode(requestCode)                .setStartFlags(startFlags)                .setProfilerInfo(profilerInfo)                .setActivityOptions(bOptions)                .setMayWait(userId)                .execute();    }        最后调用的是 ActivityStarter.execute();    

上面代码最终调用到了 startActivityAsUser 方法,在内部将所有点的参数都交给了 ActivityStarter

2.3 startActivityUnchecked()

ActivityStarter 该类包含了启动的所有逻辑,比如 Intent 解析以及任务栈等。

ActivityStarter.java

   int execute() {        try {            if (mRequest.mayWait) {                return startActivityMayWait(mRequest.caller, ...);            } else {                // todo                 return startActivity(mRequest.caller, ...);              }        } finally {            onExecutionComplete();        }    }   private int startActivity(IApplicationThread caller, Intent intent, ...) {                // 再次检查调用者权限,包括进程检查,intent检查,权限检查等        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, ...);        abort |= !mService.mIntentFirewall.checkStartActivity(intent, ...);        // 每个 Activity 都会对应一个 ActivityRecord 对象        ActivityRecord r = new ActivityRecord(mService, ...);        // todo         result = startActivityUnchecked(r, sourceRecord ...);   }    // Note: This method should only be called from {@link startActivity}.    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord ...) {        //设置初始化状态        setInitialState(r, options, inTask, ...);                //判断启动模式,并且在 mLaunchFlags 上追加对应标记        computeLaunchingTaskFlags();                //设置 Activity 的栈        computeSourceStack();                //设置 LaunchFlags 到 intent 上        mIntent.setFlags(mLaunchFlags);        //决定是否用新的栈        ActivityRecord reusedActivity = getReusableIntentActivity();                ...        // Should this be considered a new task?        int result = START_SUCCESS;        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask             && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {          newTask = true;          // 创建一个新的task来启动          result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);        } else        // todo         mSupervisor.resumeFocusedStackTopActivityLocked();            }

上面代码中会进行一些校验和判断权限,包括进程检查,intent检查,权限检查等

2.4 resumeFocusedStackTopActivityLocked()

ActivityStackSupervisor.java

    boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack...) {        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);        return false;      }

resumeTopActivityUncheckedLocked -> resumeTopActivityInnerLocked -> startSpecificActivityLocked()
ActivityStack.java

    @GuardedBy("mService")    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {        if (mStackSupervisor.inResumeTopActivity) {            Activity 存在则resume            transaction.setLifecycleStateRequest( ResumeActivityItem.obtain(next.app.repProcState,。。。);            mService.getLifecycleManager().scheduleTransaction(transaction);            不存在则调用下面这个            result = resumeTopActivityInnerLocked(prev, options);        } finally {        }        return result;    }    @GuardedBy("mService")    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {            mStackSupervisor.startSpecificActivityLocked(next, true, false);                        return true;    }

2.5 startSpecificActivityLocked -> realStartActivityLocked()

ActivityStackSupervisor.java
startSpecificActivityLocked -> realStartActivityLocked(); 到这个地方,我们就可以看到真的开始启动 activity,
后面就跟Application 里面一样了

    void startSpecificActivityLocked(ActivityRecord r ...) {        if (app != null && app.thread != null) {          try {            // 真的开始启动 activity  ,看下面的方法            realStartActivityLocked(r, app, andResume, checkConfig);            return;          } catch (RemoteException e) {          }          }    }    真的开始启动 activity    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,            boolean andResume, boolean checkConfig) throws RemoteException {        // Create activity launch transaction.        final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,                r.appToken);                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),                System.identityHashCode(r), r.info,                // TODO: Have this take the merged configuration instead of separate global                // and override configs.                mergedConfiguration.getGlobalConfiguration(),                mergedConfiguration.getOverrideConfiguration(), r.compat,                r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,                r.persistentState, results, newIntents, mService.isNextTransitionForward(),                profilerInfo));                    // Schedule transaction.        mService.getLifecycleManager().scheduleTransaction(clientTransaction);    }

ActivityManagerService

    ClientLifecycleManager getLifecycleManager() {        return mLifecycleManager;    }    

ClientLifecycleManager

    通过代码,我们可以看到,获取的client就是 ActivityThreadIApplicationThread是一个AIDL文件    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {        final IApplicationThread client = transaction.getClient();        transaction.schedule();            }

ClientTransaction

                private IApplicationThread mClient;        public void schedule() throws RemoteException {        mClient.scheduleTransaction(this);    }

ClientTransactionHandler

    //ActivityThread中没有复写scheduleTransaction,会执行到父类的方法    //public final class ActivityThread extends ClientTransactionHandler    //ClientTransactionHandler.java    public abstract class ClientTransactionHandler {            void scheduleTransaction(ClientTransaction transaction) {            transaction.preExecute(this);            //发送消息            sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);        }    }

ActivityThread.java

    case EXECUTE_TRANSACTION:        final ClientTransaction transaction = (ClientTransaction) msg.obj;        mTransactionExecutor.execute(transaction);        break;        

这里其实就是执行LaunchActivityItem的execute方法,
其赋值的地方在realStartActivityLocked()方法,大家可以回头看看,前面有这么一句代码
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),

TransactionExecutor.java

    public void execute(ClientTransaction transaction) {        final IBinder token = transaction.getActivityToken();        executeCallbacks(transaction);        executeLifecycleState(transaction);        mPendingActions.clear();        log("End resolving transaction");    }        @VisibleForTesting    public void executeCallbacks(ClientTransaction transaction) {                final List<ClientTransactionItem> callbacks = transaction.getCallbacks();        final IBinder token = transaction.getActivityToken();        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();                final int size = callbacks.size();        for (int i = 0; i < size; ++i) {            final ClientTransactionItem item = callbacks.get(i);                        item.execute(mTransactionHandler, token, mPendingActions);            item.postExecute(mTransactionHandler, token, mPendingActions);                    }    }

到这里就调用到我们熟悉的handleLaunchActivity了
LaunchActivityItem.java

    @Override    public void execute(ClientTransactionHandler client, IBinder token,            PendingTransactionActions pendingActions) {        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,                mPendingResults, mPendingNewIntents, mIsForward,                mProfilerInfo, client);        client.handleLaunchActivity(r, pendingActions, null );    }

最后调用到ActivityThread

三、 Activity实例化过程

ActivityThread.java

        @Override    public Activity handleLaunchActivity(ActivityClientRecord r,            PendingTransactionActions pendingActions, Intent customIntent) {        final Activity a = perfORMLaunchActivity(r, customIntent);                return a;    }    Activity实例化过程            private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        Activity activity = null;        try {            // 通过ClassLoader去加载需要启动的activity, 反射实例化Activity对象            java.lang.ClassLoader cl = appContext.getClassLoader();            activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);        } catch (Exception e) {        }        // 在该方法内部创建window,并设置window回调,        activity.attach(appContext, this, getInstrumentation() ...);theme                //当实例化Activity对象后,继续执行callActivityOnCreate, 继而调用Activity的onCreate,        // 这样就完成了Activity生命周期的第一个回调onCreate方法        if (r.isPersistable()) {            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);        } else {            mInstrumentation.callActivityOnCreate(activity, r.state);        }    }

下面的代码比较简单,就不贴了
frameworks/base/core/java/android/app/Instrumentation.java

四、 setContentView

这里内容太多,我们另外写一篇文章。

五、 后续生命周期

接下来就是执行 Activity 其他生命周期函数
ActivityThread.java

    @Override    public void handleStartActivity(ActivityClientRecord r,            PendingTransactionActions pendingActions) {        final Activity activity = r.activity;        // Restore instance state        if (pendingActions.shouldRestoreInstanceState()) {            if (r.isPersistable()) {                if (r.state != null || r.persistentState != null) {                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,r.persistentState);                }            } else if (r.state != null) {                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);            }        }                // Call postOnCreate()        if (pendingActions.shouldCallOnPostCreate()) {            activity.mCalled = false;            if (r.isPersistable()) {                mInstrumentation.callActivityOnPostCreate(activity, r.state,                        r.persistentState);            } else {                mInstrumentation.callActivityOnPostCreate(activity, r.state);            }        }    }    @Override    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,            String reason) {            }

写在最后:
在应用进程创建 activity 后,activity 将执行以下操作:

  1. 初始化值。
  2. 调用构造函数。
  3. 根据 activity 的当前生命周期状态,相应地调用回调方法,如 Activity.onCreate()。
    通常,onCreate() 方法对加载时间的影响最大,因为它执行工作的开销最高:加载和渲染视图,以及初始化运行 activity 所需的对象。

六、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

来源地址:https://blog.csdn.net/fumeidonga/article/details/132146922

--结束END--

本文标题: Android Activity启动流程一:从Intent到Activity创建

本文链接: https://lsjlt.com/news/384577.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作