Activity有两种
- 由Launcher启动的根actvity
- 由activity启动的子activity
根activity在配置文件中声明
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
根Activity的启动过程
首先PackageManagerService负责应用程序的安装
1 对manifest配置文件解析,保存各个组件信息
2 Launcher(也是一个Activity)在启动过程中向PackageManageService查询所有action=”action.Main” category = intent.CATEGORY_LAUNCHER 的activity
3 为符合条件的每个activity创建快捷图标,并将信息和图标绑定起来在点击图标的时候执行Launcher的startActivitySafely方法
boolean startActivitySafely(View v, Intent intent, Object tag) {
boolean success = false;
try {
success = startActivity(v, intent, tag);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
}
return success;
}
- 接着执行startActivity(View v, Intent intent, Object tag)
boolean startActivity(View v, Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//启动标志位设置为1,在新的任务中启动
try {
// Only launch using the new animation if the shortcut has not opted out (this is a
// private contract between launcher and may be ignored in the future).
boolean useLaunchAnimation = (v != null) &&
!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
if (useLaunchAnimation) {
ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
v.getMeasuredWidth(), v.getMeasuredHeight());
startActivity(intent, opts.toBundle());// 带启动动画(缩放和弹出动画)
} else {
startActivity(intent);
}
return true;
} catch (SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Launcher does not have the permission to launch " + intent +
". Make sure to create a MAIN intent-filter for the corresponding activity " +
"or use the exported attribute for this activity. "
+ "tag="+ tag + " intent=" + intent, e);
}
return false;
}
- 执行startActivity(intent)
public void startActivity(Intent intent){
startActivityForResult(intent,-1);//不需要知道返回结果
}
- 接着看一下startActivityForResult
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
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;
}
} 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);
}
}
}
mInstrumentation是Activity的成员变量,用来监控应用程序与系统之间的交互操作。
mInstrumentation.execStartActivity 有个ApplicationThread参数是ActivityThread的内部类型weiApplicationThread的Binder本地对象,mInstrumentation最终将这个ApplicationThread传递给ActivityManagerService,AMS通过它通知Launcher进入pause状态。
mToken(IBinder)是一个Binder代理对象,指向了AMS中ActivityRecord的Binder本地对象,ActivityRecord用来维护组建的运行状态和信息,这样AMS就可以获得Launcher组件的信息了。
- 接着看mInstrumentation.execStartActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.setAllowFds(false);
intent.migrateExtraStreamToClipData();
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
ActivityManagerNative.getDefault().startActivity 获得一个AMS代理,最终调用ActivityManagerProxy.startActivity
public int startActivity(IApplicationThread caller, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, String profileFile,
ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
data.writeString(profileFile);
if (profileFd != null) {
data.writeInt(1);
profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);// 向AMS发送进程间通信
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
这样通过ActivityManagerProxy向AMS发送一个进程间通信请求,启动activity。