Activity启动源码分析

在Android系统中,有两种操作会引发Activity的启动,一种用户点击应用程序图标时,Launcher会启动应用的主Activity;应用程序的默认Activity启动起来后,又可以通过调用startActvity启动新的Activity,每一个Activity都可以在内部启动新的Activity来完成应用程序的功能。

Activity的启动流程,一般我们都是通过startActivity或startActivityForResult来启动目标activity,那么我们就由此出发探究系统是如何实现目标Activity的启动的~

Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);

首先是startActivity 然后会走到如下的方法:

@Override
    public void startActivity(Intent intent) {
   
        this.startActivity(intent, null);
    }

调用startActivityForResult来进一步处理,第二个参数传入-1表示不需要这个Actvity结束后的返回结果

@Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
   
        if (options != null) {
   
            startActivityForResult(intent, -1, options);
        } else {
   
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

在startActivityForResult中会先调用Instrumentation.execStartActivity来获取一个ActivityResult实例,ActivityResult是用来描述目标activity执行结果的
所以activity的启动肯定跟Instrumentation.execStartActivity有关
mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象
调用ActivityThread.sendActivityResult来把启动结果发送出去,其最终是通过handler发送一个SEND_RESULT message
Instrumentation:每一个应用程序都只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或者打开某个Activity时,都需要通过Instrumentation来进行具体的操作

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());
            }
            if (requestCode >= 0) {
   
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
   
            if (options != null) {
   
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
   
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
   
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
   
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        if (mActivityMonitors != null) {
   
            synchronized (mSync) {
   
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
   
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    ActivityResult result = null;
                    if (am.ignoreMatchingSpecificIntents()) {
   
                        result = am.onStartActivity(intent);
                    }
                    if (result != null) {
   
                        am.mHits++;
                        return result;
                    } else if (am.match(who, null, intent)) {
   
                        am.mHits++;
                        if (am.isBlocking()) {
   
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
   
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            //调用AMS的startActivity
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
   
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

调用了ActivityManager的getService()

    public static IActivityManager getService() {
   
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
   
                @Override
                protected IActivityManager create() {
   
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

getService()在内部调用了IActivityManagerSingleton.get(),在get()中先通过ServiceManager.getService获取一个AMS的binder,然后调用IActivityManager.Stub.asInterface使用AIDL进行IPC与AMS进行通信

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
   
        
		···
}

ActivityManagerService是IActivityManager.Stub的子类,我们通过这个代理类和系统进程进行通信

接着看ActivityManagerService 的startActivity()

@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());
    }

调用了startActivityAsUser()

@Override
    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) {
   
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

继续调用同名的方法startActivityAsUser

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();

    }

mActivityStartController是一个ActivityStartController对象,mActivityStartController调用了obtainStarter方法来获取一个ActivityStarter对象,从而启动任务交给了ActivityStarter

进入到ActivityStarter的execute方法

int execute() {
   
        try {
   
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
   
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            } else {
   
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            }
        } finally {
   
            onExecutionComplete();
        }
    }

由于在AMS的startActivityAsUser中调用了setMayWait方法,也就是ActivityStarter的setMayWait方法,if判断条件满足

ActivityStarter setMayWait(int userId) {
   
        mRequest.mayWait = true;
        mRequest.userId = userId;

        return this;
    }

进入ActivityStarter的startActivityMayWait方法

private 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 globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
            int userId, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
   
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors()) {
   
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
        boolean componentSpecified = intent.getComponent() != null;

        final int realCallingPid = Binder.getCallingPid();
        final int realCallingUid = Binder.getCallingUid();

        int callingPid;
        if (callingUid >= 0) {
   
            callingPid = -1;
        } else if (caller == null) {
   
            callingPid = realCallingPid;
            callingUid = realCallingUid;
        } else {
   
            callingPid = callingUid = -1;
        }

        // Save a copy in case ephemeral needs it
        final Intent ephemeralIntent = new Intent(intent);
        // Don't modify the client's object!
        intent = new Intent(intent);
        if (componentSpecified
                && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
                && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
                && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
                && mService.getPackageManagerInternalLocked()
                        .isInstantAppInstallerComponent(intent.getComponent())) {
   
            // intercept intents targeted directly to the ephemeral installer the
            // ephemeral installer should never be started with a raw Intent; instead
            // adjust the intent so it looks like a "normal" instant app launch
            intent.setComponent(null /*component*/);
            componentSpecified = false;
        }

        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                0 /* matchFlags */,
                        computeResolveFilterUid(
                                callingUid, realCallingUid, mRequest.filterCallingUid));
        if (rInfo == null) {
   
            UserInfo userInfo = mSupervisor.getUserInfo(userId);
            if (userInfo != null && userInfo.isManagedProfile()) {
   
                // Special case for managed profiles, if attempting to launch non-cryto aware
                // app in a locked managed profile from an unlocked parent allow it to resolve
                // as user will be sent via confirm credentials to unlock the profile.
                UserManager userManager = UserManager.get(mService.mContext);
                boolean profileLockedAndParentUnlockingOrUnlocked = false;
                long token = Binder.clearCallingIdentity();
                try {
   
                    UserInfo parent = userManager.getProfileParent(userId);
                    profileLockedAndParentUnlockingOrUnlocked = (parent != null)
                            && userManager.isUserUnlockingOrUnlocked(parent.id)
                            && !userManager.isUserUnlockingOrUnlocked(userId);
                } finally {
   
                    Binder.restoreCallingIdentity(token);
                }
                if (profileLockedAndParentUnlockingOrUnlocked) {
   
                    rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                            PackageManager.MATCH_DIRECT_BOOT_AWARE
                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                            computeResolveFilterUid(
                                    callingUid, realCallingUid, mRequest.filterCallingUid));
                }
            }
        }
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        synchronized (mService) {
   
            final ActivityStack stack = mSupervisor.mFocusedStack;
            stack.mConfigWillChange = globalConfig != null
                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;
            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                    "Starting activity when config will change = " + stack.mConfigWillChange);

            final long origId = Binder.clearCallingIdentity();

            if (aInfo != null &&
                    (aInfo.applicationInfo.privateFlags
                            & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
                    mService.mHasHeavyWeightFeature) {
   
                // This may be a heavy-weight process!  Check to see if we already
                // have another, different heavy-weight process running.
                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
   
                    final ProcessRecord heavy = mService.mHeavyWeightProcess;
                    if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
                            || !heavy.processName.equals(aInfo.processName))) {
   
                        int appCallingUid = callingUid;
                        if (caller != null) {
   
                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
                            if (callerApp != null) {
   
                                appCallingUid = callerApp.info.uid;
                            } else {
   
                                Slog.w(TAG, "Unable to find app for caller " + caller
                                        + " (pid=" + callingPid + ") when starting: "
                                        + intent.toString());
                                SafeActivityOptions.abort(options);
                                return ActivityManager.START_PERMISSION_DENIED;
                            }
                        }

                        IIntentSender target = mService.getIntentSenderLocked(
                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
                                appCallingUid, userId, null, null, 0, new Intent[] {
    intent },
                                new String[] {
    resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
                                        | PendingIntent.FLAG_ONE_SHOT, null);

                        Intent newIntent = new Intent();
                        if (requestCode >= 0) {
   
                            // Caller is requesting a result.
                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
                        }
                        newIntent
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Activity启动模式是Android应用程序中非常重要的概念,它决定了Activity启动方式和生命周期的管理方式。在Android中,Activity启动模式主要有以下几种: 1. standard:标准模式。默认情况下,每次启动Activity时都会创建一个新实例,并放入任务栈中。如果该Activity已经存在任务栈中,则会将该Activity放到栈顶,并重新调用其onCreate()方法。 2. singleTop:栈顶复用模式。如果新启动Activity已经存在任务栈的栈顶,则不会创建新实例,而是将已有的实例作为当前任务的Activity,并调用其onNewIntent()方法。如果新启动Activity不在栈顶,则会创建新实例,并将其放到任务栈的栈顶。 3. singleTask:栈内复用模式。如果新启动Activity已经存在任务栈中,则不会创建新实例,而是将已有的实例作为当前任务的Activity,并将其上面的Activity全部出栈,调用其onNewIntent()方法。如果新启动Activity不存在任务栈中,则会创建新实例,并放到任务栈的栈顶。 4. singleInstance:单例模式。在一个新的任务栈中创建Activity,并且该任务栈中只有该Activity实例。如果该Activity已经存在于其他任务栈中,则会将该任务栈中的该Activity实例移动到新的任务栈中。 下面是Activity源码分析: 1. standard模式 在Activity源码中,标准模式是默认的启动模式。当我们使用startActivity()方法启动一个Activity时,会调用ActivityStackSupervisor类中的startActivityLocked()方法。在该方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈。如果存在,则会将当前Activity放到该任务栈的栈顶,并调用其onCreate()方法。如果不存在,则会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。 2. singleTop模式 当我们在Manifest文件中设置Activity启动模式为singleTop时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈,并判断当前Activity是否在栈顶。如果在栈顶,则会调用其onNewIntent()方法。如果不在栈顶,则会创建一个新的实例,并放到该任务栈的栈顶。 3. singleTask模式 当我们在Manifest文件中设置Activity启动模式为singleTask时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈。如果存在,则会找到该任务栈中的栈顶Activity,并将其上面的所有Activity出栈。然后将当前Activity放到该任务栈的栈顶,并调用其onNewIntent()方法。如果不存在,则会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。 4. singleInstance模式 当我们在Manifest文件中设置Activity启动模式为singleInstance时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。如果该Activity已经存在于其他任务栈中,则会将该任务栈中的该Activity实例移动到新的任务栈中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值