您的位置:首页 > 大数据 > 人工智能

基于N源码的Activity的启动过程分析

2016-09-22 13:47 357 查看
对于该主题的文章,网上泛滥,为了加深印象,最好还是自己跟一遍源码,这样对框架的认识以及对应用的控制都是很有帮助的。

推荐老罗的一些列文章:

Android应用程序的Activity启动过程简要介绍和学习计划

老罗的博客写的非常好,但分析的源码有点老,不过大体思路是不会变的。我这里就基于android 7.0的源码来跟下这个流程,希望能帮到大家。

分析之前,大家一定要对AIDL的使用有个认识,这样看源码才不会迷糊,不懂的可以看下之前发表的文章:AIDL的简单使用

重要的是脑海里有这幅图:



记住这几点:

1、服务端有个中间者Stub(这个名称可以自定定义,比如下面要将的ActivityManagerNative),记住它继承Binder,实现接口。

2、服务端会有一个真正的实现者,它继承Stub,还记得我们在用AIDL的时候也会这样用。比如这里的ActivityManagerServices。

3、客户端有个中间者Proxy,在跨进程的时候都会这样获取它,proxy=stub.asInterface(binder),proxy里面会有一个binder对象,调用代理的方法里面会调用binder对象的transact方法,它会跨进程进入stub里的onTransact方法里,从上图也能看出。

理解这三点后,我们可以来分析Activity的启动过程了。

首先在应用里面启动Activity:

public void startActivityTest(){
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}

接着会进入Activity.java里面:

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

这里传入的options为null,接着会走下面方法:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);

这里会看到几个重要的类,一个Instrumentation类,它是Activity启动的帮助类,一个是ActivityThread类,它主要管理主线程应用程序的执行流程。它有个内部类ApplicationThread:

private class ApplicationThread extends ApplicationThreadNative {

这是啥?他继承ApplicationThreadNative:

public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread {

看到没有,他继承Binder,实现接口。这不就是服务端的Stub吗?ApplicationThread是服务端的实现者,要理解这里的服务端是在客户端这边。

这个地方可以先记住,后面会用到,继续我们的流程,在startActivityForResult中会转到Instrumentation中执行,并且传递了一个binder的实现者ApplicationThread。

进入Instrumentation.java

public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManagerNative.getDefault()
.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);
}

这里又出现一个重要的类,ActivityManagerNative:

public abstract class ActivityManagerNative extends Binder implements IActivityManager
<pre class="java" name="code">    static public IActivityManager getDefault() {
return gDefault.get();
}


可以明显看到它也是服务端的中间者stub,接着看下gDefault:

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
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;
}
};

它是个单例类,调用get方法,如果没有初始化就会走进create方法。这里会从服务总管ServiceManager里面拿到binder对象,然后看到IActivityManager am = asInterface(b);是不是很熟悉?应该是获取本地代理吧:

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

果然如此,这里返回ActivityManagerProxy类型本地代理,上面startActivity就会走进代理里面:

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
.
.
.
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
.
.
return result;
}

这里mRemote就是远程binder对象,调用transact就会进入stub(ActivityManagerNative)中的onTransact方法:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
String resultWho = data.readString();
int requestCode = data.readInt();
int startFlags = data.readInt();
ProfilerInfo profilerInfo = data.readInt() != 0
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}

上面startActivity会走进Stub的实现者,谁是stub的实现者,也就是说谁继承ActivityManagerNative?毋庸置疑,当然是赫赫有名的ActivityManagerService:

public final class ActivityManagerService extends ActivityManagerNative

接着跟踪,进入startActivity:

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) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null);
}

可以看到进入了ActivityStarter.java中的startActivityMayWait函数,接着又进入startActivityLocked方法:

final 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, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask);
}

又进入了startActivityLocked方法:

final 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, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
doPendingActivityLaunchesLocked(false);
}
final void doPendingActivityLaunchesLocked(boolean doResume) {
while (!mPendingActivityLaunches.isEmpty()) {
final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
try {
final int result = startActivityUnchecked(
pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
postStartActivityUncheckedProcessing(
pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord,
mTargetStack);
} catch (Exception e) {
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
pal.sendErrorResult(e.getMessage());
}
}
}

在startActivityUnchecked函数中:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}

转到了ActivityStackSupervisor.java中的resumeFocusedStackTopActivityLocked函数:

boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}

接着又进入ActivityStack.java中的resumeTopActivityUncheckedLocked函数,好复杂。。。又进入resumeTopActivityInnerLocked函数:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
startPausingLocked(userLeaving, false, true, dontWaitForPause);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}

startPausingLocked应该是暂停启动Activity的那个Activity,然后又回到ActivityStackSupervisor中的startSpecificActivityLocked函数:

void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);

r.task.stack.setLaunchTime(r);

if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}

// If a dead object exception was thrown -- fall through to
// restart the application.
}

mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}

这里因为启动的Activity不是应用的第一个Activity所以上面app的信息不为null,进入realStartActivityLocked中:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
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);
}

这里的app.thread是远程binder代理,它是在ActivityManagerNative中的onTransact中初始化:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
static public IApplicationThread asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IApplicationThread in =
(IApplicationThread)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}

return new ApplicationThreadProxy(obj);
}

可以看到这个代理是ApplicationThreadProxy类型,调用scheduleLaunchActivity会进入stub实现类(ApplicationThread)里面:

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) {
.
.
sendMessage(H.LAUNCH_ACTIVITY, r);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
mH.sendMessage(msg);
}

这里的mH是handler类型,发消息让它切换到主线程处理:

private class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;


进入handleLaunchActivity:

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

进入handleResumeActivity:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
}
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
Context appContext = createBaseContextForActivity(r, activity);
Configuration config = new Configuration(mCompatConfiguration);
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);
}

终于可以看到这里用Instrumentation创建Activity,接着创建Application、ContextImpl、Configuration等,接着调用Activity的attach函数,将创建的对象关联到Activity。

Activity的启动过程就跟踪到这里,中间有些函数描述的不是很清楚,下面给出一张图来总结下:






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  activity 源码 aidl binder