源码基于API26
mParent干嘛来着,带着这个疑问上车了
通过源码发现在Activity中attach()方法中赋值了,事实上还有个方法也可以赋值,即setParent(Activity parent).
不多说直接看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) {
...
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;
...
}
在上面发现,哎呀这个parent也是个Activity啊,那这个mParent就是当前activity的父activity
那什么时候会执行attach()呢,熟悉activity启动流程的同学知道在ActivityThread中performLaunchActivity()中执行的
不熟悉的往这里看源码探探之StartActivity(一)
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
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.parent即是我们的mParent,而r为ActivityClientRecord类,activity的一个记录类,记录了很多启动activity的信息,咱先不管,我们直接去找哪里执行了performLaunchActivity()就行。
熟悉activity启动的会知道,会在handleLaunchActivity()中执行,handleLauchActivity()的ActivityClientRecord也是由上一个类传过来的,继续往上,发现在scheduleLaunchActivity()中新建了ActivityClientRecord类的实例,但是,找不到r.parent被赋值,也就是StartActivity跟这个没半毛钱关系,那我不白写了吗
作为屌丝程序员就不想去发现这个mParent是个啥吗
回到最后出现r.parent的地方performLauchActivity(),发现还有一个地方执行了这个方法
public final Activity startActivityNow(Activity parent, String id,
Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
Activity.NonConfigurationInstances lastNonConfigurationInstances) {
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = 0;
r.intent = intent;
r.state = state;
//眼睛往这里
r.parent = parent;
r.embeddedID = id;
r.activityInfo = activityInfo;
r.lastNonConfigurationInstances = lastNonConfigurationInstances;
if (localLOGV) {
ComponentName compname = intent.getComponent();
String name;
if (compname != null) {
name = compname.toShortString();
} else {
name = "(Intent " + intent + ").getComponent() returned null";
}
Slog.v(TAG, "Performing launch: action=" + intent.getAction()
+ ", comp=" + name
+ ", token=" + token);
}
return performLaunchActivity(r, null);
}
找到了吧,赋值了吧,在这里新建了ActivityClientRecord,并赋值了r.parent
在弃用了的LocalActivityManager类的moveToState方法中有执行
private void moveToState(LocalActivityRecord r, int desiredState) {
...
r.activity = mActivityThread.startActivityNow(
mParent, r.id, r.intent, r.activityInfo, r, r.instanceState, instance);
...
}
这里有用到了mParent,现在看看LocalActivityManager
public LocalActivityManager(Activity parent, boolean singleMode) {
mActivityThread = ActivityThread.currentActivityThread();
mParent = parent;
mSingleMode = singleMode;
}
这里的mParent是通过实例化LocalActivityManger赋值的,由于LocalActivityManger已经弃用了,那以前LocalActivityManger干嘛用的
Create a new LocalActivityManager for holding activities running within the given parent.
只能用蹩脚的英语翻译一波,也就是管理持有一个运行于给定父activity中的activity
通俗一点就是,管理子activity
从我学习android开始就没有用过这个东东,这类情况好像跟fragment类似,应该是被fragment取代了,然后就被弃用了
其实在TabActivity中才会出现这种情况,也会用到LocalActivityManger来管理Activity,由于已经弃用了我就不分析了,感兴趣自行分析。
本文,只分析了mParent在StartActivity中的作用,结论是半毛线关系都没有,一直为空