Activity的启动流程

                 很早之前就想写一篇关于Activity启动流程的文章,但是很多时候都很难坚持下来,一个是因为工作比较忙的原因,第二个是因为Activity的启动流程太过复杂,不敢轻易下手。最近一段时间公司不忙,加上自己有大把的时间去研究源码,所以便把Activity的启动流程再次好好看了一遍,顺便记录下来供以后自己复习。

 

 一般开始进入Activity的源码分析是从Activity$startActivity开始的,但是其实真正的入口却并不是这个,而是Activity$main()方法,所以我们先来看看Activity$main()方法里面做了些什么事情

public static void main(String[] args) {
    
        // 初始化Looper对象  
        Looper.prepareMainLooper();

        // 创建ActivityThread
        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        // 开始循环
        Looper.loop();

}

看看thread.attach(false);里面做了些什么事情

private void attach(boolean system) {
    // 省略部分代码
    // IActivityManager是一个接口,具体的实现类是ActivityManagerService
    final IActivityManager mgr = ActivityManager.getService();
    try {
        // mAppThread是ActivityThread类里面的一个内部类
        mgr.attachApplication(mAppThread);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    // 省略部分代码
}

那么ActivityManagerService是什么呢?

ActivityManagerService简称AMS,它是android中很重要的一个服务,它统筹管理着android的四大组件;统一调度各应用进程;AMN由Binder类派生,实现了IActivityManager接口,客户端使用ActivityManager类,因为AMS是系统核心服务,很多API不能直接访问,需要通过ActivityManager来进行处理

 

好,那么我们现在开始进入正题

// 我们调用的startActivity最终都会执行到这里
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
    //  Instrumentation和Activity有点类似,只不过Activity是需要一个界面的,而Instrumentation并不是这样的
    //  我们可以将它理解为一种没有图形界面的,具有启动能力的,用于监控其他类(用Target Package声明)的工具类
    //  注意mMainThread.getApplicationThread()获取的是ApplicationThread的实例
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, this,
            intent, requestCode, options);
}

进入到Instrumentation里面的execStartActivity

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        // 省略部分代码
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            // ActivityManager.getService().startActivity方法最终会执行到ActivityManagerService()方法里面的startActivity
            // 需要注意的是这里通过binder已经进行了一次跨进程通信
            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;
}

进入到ActivityManagerService里面的startActivity()

@Override
public int startActivity(IBinder whoThread, String callingPackage,
                Intent intent, String resolvedType, Bundle bOptions) {
            checkCaller();

            int callingUser = UserHandle.getCallingUserId();
            TaskRecord tr;
            IApplicationThread appThread;
            synchronized (ActivityManagerService.this) {
                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
                if (tr == null) {
                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
                }
                // 注意这里的跨进程采用的方式是AIDL
                appThread = IApplicationThread.Stub.asInterface(whoThread);
                if (appThread == null) {
                    throw new IllegalArgumentException("Bad app thread " + appThread);
                }
            }
            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
                    resolvedType, null, null, null, null, 0, 0, null, null,
                    null, bOptions, false, callingUser, tr, "AppTaskImpl");
}

进入到ActivityManagerService里面的startActivityMayWait()

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 globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            TaskRecord inTask, String reason) {
            // 省略部分代码
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);
           // 省略部分代码
            return res;
        }
}

进入到ActivityStarter里面的startActivityMayWait()

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
        // 省略部分代码
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask);
        // 省略部分代码
        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask) {
        // 省略部分代码
        doPendingActivityLaunchesLocked(false);
        // 省略部分代码
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }
}

final void doPendingActivityLaunchesLocked(boolean doResume) {
        while (!mPendingActivityLaunches.isEmpty()) {
            final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
            final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
            try {
                // 执行到这里
                startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
                        null, null /*outRecords*/);
            } catch (Exception e) {
                Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
                pal.sendErrorResult(e.getMessage());
            }
        }
}

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
            // 省略部分代码
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
            // 省略部分代码
        return result;
}

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
    // 省略部分代码
    mSupervisor.resumeFocusedStackTopActivityLocked();
    
    // 省略部分代码
    return START_SUCCESS;
}

进入到ActivityStackSupervisor里面的resumeFocusedStackTopActivityLocked()

 boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
    }

boolean resumeFocusedStackTopActivityLocked(
    ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        // 省略部分代码
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        // 省略部分代码
}

进入到ActivityStack里面的resumeTopActivityUncheckedLocked()

ActivityStack类,顾名思义就是用来管理Activity入栈退栈的,继续向下看

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    // 省略部分代码  
    result = resumeTopActivityInnerLocked(prev, options);
    // 省略部分代码  
    return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
	// 省略部分代码  
	mStackSupervisor.startSpecificActivityLocked(next, true, true);
    // 省略部分代码  
}

进入到ActivityStackSupervisor里面的startSpecificActivityLocked()

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
    // 省略部分代码  
	realStartActivityLocked(r, app, andResume, checkConfig);
    // 省略部分代码  
}

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
	// 省略部分代码 
	// 找了半天终于到了关键代码,有木有很激动,首先我们要搞清楚app.thread是什么?
	// 查看源码得知,app.thread是IApplicationThread thread; 而IApplicationThread 是一个接zhong口,具体实现是ApplicationThread
	// 所以我们可以判断app.thread.scheduleLaunchActivity最终会执行到ActivityThread里面ApplicationThread类里面的scheduleLaunchActivity方法
	app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    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, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
	// 省略部分代码     
}

终于走到我们熟悉的地方了

进入到ActivityThread类

@Override
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) {

            updateProcessState(procState, false);
            // 把Activity的一些基本信息封装成ActivityClientRecord
            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);
            // 最最重要的代码, 通过发送消息来启动Activity
            sendMessage(H.LAUNCH_ACTIVITY, r);
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        
        //  省略部分代码
        Activity a = performLaunchActivity(r, customIntent);

        //  省略部分代码
        handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
}

performLaunchActivity(r, customIntent);和handleResumeActivity()就是我们分析的重点了

 

首先来分析performLaunchActivity(r, customIntent);

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        
        // 获取到ActivityInfo类
        // ActivityInfo用来存放一些关于Activity的信息		
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }
        // 获取Activity的一些属性,包括包名等等
        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        // 创建Activity的上下文Context,ContextImpl是Context一个子类
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
		    // 获取类加载器ClassLoader
            java.lang.ClassLoader cl = appContext.getClassLoader();
			// 通过反射的方式生成Activity实例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
		    // 获取Application 
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            // 如果Activity不为空   
            if (activity != null) {
                // 声明Window属性
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                appContext.setOuterContext(activity);
				// 进入到Activity的attach方法
                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, window, r.configCallback);

                // 执行到Activity的create方法 
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
				r.activity = activity;
                r.stopped = true;
				// 执行到Activity的start方法 
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
            }
            r.paused = true;
            mActivities.put(r.token, r);
        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
}
Activity的attach()方法
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,
            Window window, ActivityConfigCallback activityConfigCallback) {
        attachBaseContext(context);

        // 实例化Window对象PhoneWindow
		// 设置Window的一些属性
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }
        mUiThread = Thread.currentThread();

        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }
        // 实例化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());
        }
		// 把WindowManager设置给mWindowManager
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;

        mWindow.setColorMode(info.colorMode);
}	

看来performLaunchActivity里面做了很多事情呀,我们来总结一下:

1.调用了生命周期里面的onAttach(),onCreate(),onStart()方法

2.Activity是通过反射来生成实例的

3.在onAttach()方法里面,new了一个Window对象PhoneWindow并给PhoneWindow设置了一些属性。同时创建了WindowManager对象并把WindowManager的实例赋值给mWindowManager

4.WindowManager是通过调用系统服务获取到的

 

接下来我们看看handleResumeActivity里面做了一些什么操作

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
		// 获取Activity的一些信息	
        ActivityClientRecord r = mActivities.get(token);
        
		// 执行生命周期里面的onResume方法
        r = performResumeActivity(token, clearHide, reason);

        if (r != null) {
		    // 拿到当前的Activity  
            final Activity a = r.activity;
            
            if (r.window == null && !a.mFinished && willBeVisible) {
			    // 设置我们的Window为PhoneWindow
                r.window = r.activity.getWindow();
				// 拿到我们的DecorView
                View decor = r.window.getDecorView();
				// 先隐藏我们的DecorView
                decor.setVisibility(View.INVISIBLE);
				// 拿到我们的WindowManager
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (r.mPreserveWindow) {
                    a.mWindowAdded = true;
                    r.mPreserveWindow = false;
                    // Normally the ViewRoot sets up callbacks with the Activity
                    // in addView->ViewRootImpl#setView. If we are instead reusing
                    // the decor view we have to notify the view root that the
                    // callbacks may have changed.
                    ViewRootImpl impl = decor.getViewRootImpl();
                    if (impl != null) {
                        impl.notifyChildRebuilt();
                    }
                }
                if (a.mVisibleFromClient) {
                    if (!a.mWindowAdded) {
                        a.mWindowAdded = true;
						// 将DecorView设置进去
                        wm.addView(decor, l);
                    } else {
                        // The activity will get a callback for this {@link LayoutParams} change
                        // earlier. However, at that time the decor will not be set (this is set
                        // in this method), so no action will be taken. This call ensures the
                        // callback occurs with the decor set.
                        a.onWindowAttributesChanged(l);
                    }
                }

            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
            } else if (!willBeVisible) {
                if (localLOGV) Slog.v(
                    TAG, "Launch " + r + " mStartedActivity set");
                r.hideForNow = true;
            }

            // Get rid of anything left hanging around.
            cleanUpPendingRemoveWindows(r, false /* force */);

            // The window is now visible if it has been added, we are not
            // simply finishing, and we are not starting another activity.
            if (!r.activity.mFinished && willBeVisible
                    && r.activity.mDecor != null && !r.hideForNow) {
                if (r.newConfig != null) {
                    performConfigurationChangedForActivity(r, r.newConfig);
                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                            + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
                    r.newConfig = null;
                }
                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                        + isForward);
                WindowManager.LayoutParams l = r.window.getAttributes();
                if ((l.softInputMode
                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                        != forwardBit) {
                    l.softInputMode = (l.softInputMode
                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                            | forwardBit;
                    if (r.activity.mVisibleFromClient) {
                        ViewManager wm = a.getWindowManager();
                        View decor = r.window.getDecorView();
						// 更新我们的视图
                        wm.updateViewLayout(decor, l);
                    }
                }

                r.activity.mVisibleFromServer = true;
                mNumVisibleActivities++;
                if (r.activity.mVisibleFromClient) {
                    r.activity.makeVisible();
                }
            }

        } else {
            // If an exception was thrown when trying to resume, then
            // just end this activity.
            try {
                ActivityManager.getService()
                    .finishActivity(token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
}	

handleResumeActivity()方法主要做了两件事情:

1.执行了生命周期里面的onResume()方法

2.将DecorView添加到PhoneWindow里面去

 

到这里,Activity的启动流程就分析完毕了,当然,我只是菜鸟一个,可能分析的有些地方还不到位。具体的话各位还是多看看源码,看多了自然就懂了,欢迎大家在下面留言

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值