赞
踩
在Android系统中,Activity作为应用的核心组件之一,且是用于与用户进行交互的。我们不仅要知道怎么创建一个Activity,怎么控制一个Activity中的控件显示等。其实也应该更深入的了解下,一个Activity是怎么样被启动的,这些涉及到了framework层的知识,那下面就让我们开始了解下。
在Android系统中,有两种操作会引发Activity的启动,一种用户点击应用程序图标时,Launcher会为我们启动应用程序的主Activity;应用程序的默认Activity启动起来后,它又可以在内部通过调用startActvity接口启动新的Activity。
当我们从手机屏幕上点击一个应用程序的图标的时候,默认启动的Acitivity就是我们在AndroidManifest.xml设置的:
- <activity android:name=".MainActivity"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" /> </span>
- </intent-filter>
- </activity>
在内部启动activity,是调用startActvity接口启动的,应用程序框架层会根据对应的字符串来找到其对应的Activity.
- <activity
- android:name="jh.activity.ActivityTest"</span>
- android:screenOrientation="portrait" >
- </activity>
无论是通过点击应用程序图标来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都要借助于应用程序框架层的ActivityManagerService服务进程。前面在ActivityManager中的Proxy模式一文中有介绍过ActivityMnagerService是一个非常重要的接口,它不但负责启动Activity和Service,还负责管理Activity和Service。
Android启动Activity的大致流程如图:
下面我们就通过分析源码,结合上面的大致流程图,来探清Activity启动流程:
- public class Activity extends ContextThemeWrapper
- implements LayoutInflater.Factory,
- Window.Callback, KeyEvent.Callback,
- OnCreateContextMenuListener, ComponentCallbacks {
- ...........
- @Override
- public void startActivity(Intent intent) {
- startActivityForResult(intent, -1);
- }
-
- ..........
- ..........
- }
这步其实是调用了startActivityForResult函数,-1的话就不需要返回,requestcode>0的才需要在onActivityResult()得到返回的结果。
public void startActivityForResult(Intent intent, int requestCode) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
.......
}
mInstrumentation是成员变量,由他来执行Activity启动。mMainThread也是成员变量,他的类型是ActivityThread
mMainThread.getApplicationThread()获得ApplicationThread成员变量。他继承了ApplicationNative。
Instrumentation.execStartActivity:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
............
try {
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
ActivityManagerNative.getDefault()得到的对象是ActivityManagerService接口,intent.resolveTypeIfNeeded返回这个intent的MIME类型.
ActivityManagerService.startActivity:
源码:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
..........
public final int startActivity(IApplicationThread caller,
Intent intent, String resolvedType, Uri[] grantedUriPermissions,
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded,
boolean debug) {
return mMainStack.startActivityMayWait(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded, debug, null, null);
}
..........
}
这里就是调用了mMainStack.startActivityMayWait函数,mMainStack的类型是ActivityStack。
ActivityStack.startActivityMayWait:
public class ActivityStack{
...............
final int startActivityMayWait(IApplicationThread caller,
Intent intent, String resolvedType, Uri[] grantedUriPermissions,
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded,
boolean debug, WaitResult outResult, Configuration config) {
............
ActivityInfo aInfo;
try {
ResolveInfo rInfo =
AppGlobals.getPackageManager().resolveIntent(
intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| ActivityManagerService.STOCK_PM_FLAGS);
aInfo = rInfo != null ? rInfo.activityInfo : null;
} catch (RemoteException e) {
aInfo = null;
}
..........
synchronized (mService) {
..............
if (mMainStack && aInfo != null &&
(aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
..............
}
}
int res = startActivityLocked(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, aInfo,
resultTo, resultWho, requestCode, callingPid, callingUid,
onlyIfNeeded, componentSpecified);
if (mConfigWillChange && mMainStack) {
.............
}
Binder.restoreCallingIdentity(origId);
if (outResult != null) {
..............
}
return res;
}
}
}
这个函数里面的东西略多,我们找几个相关的解析下,aInfo.applicationInfo.packageName这个获得的就是程序的包名,aInfo.name的值是当前Activity的名字。继续调用startActivityLocked进一步处理了。
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType,
Uri[] grantedUriPermissions,
int grantedMode, ActivityInfo aInfo, IBinder resultTo,
String resultWho, int requestCode,
int callingPid, int callingUid, boolean onlyIfNeeded,
boolean componentSpecified) {
int err = START_SUCCESS;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。