ActivityThead 启动页面分析
文章目录
ActivityThead 路径之前的回忆
- 上一篇文章我们分析了应用是如何从左面点击 到启动ActivityThread 的main方法的,简单的流程如下
-
- 点击图标 -->进入Activity 的startActivity()方法,而这个方法最终交给了 Intrumentation ,再交给ActivityManagerService(我们看到的是IActivityManager ActivityManagerService是其具体的实现类),再交给ActivityStack(高版本中叫做ActivityStarter),在这里面进行了判断,如果当前进程不存在,那么我们首先会去创建一个应用的进程, 交给了额Zygote以及ZygoteInit类进行处理,他们内部则是开启了服务端的socket用来进行通信,并启动SystemServer,最终会走到RuntimeInit中,从这个了类中利用反射的形式开启了ActivityThread 的main方法。其中zygote主要机型一些资源的资源的加载,而SystemServer 则是开启了祥光的各种Service。上半部分就回忆到这里。
ActivityThread 的main方法
不多说上代码
// 本文依旧基于API_15,main方法就这么简单,几行代码
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Process.setArgV0("<pre-initialized>");
//整个应用的的UI线程的线程looper 也就是mainlooper启动
Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
//创建了一个ActivitThread并和当前的应用进行绑定,其中包含了我们Applciation的创建,接下来我们逐步来看
ActivityThread thread = new ActivityThread();
thread.attach(false);
Looper.loop();
}
我们进入到attach方法进行查看,到底都干了啥!
private void attach(boolean system) {
sThreadLocal.set(this);
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//ActivityManagerService和ApplicationThread(这个类我们后面会讲,但我们要知道他是为了ActivityThread和ActivityManagerService同行的通道,原理还是IPC机制)进行绑定,
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
android.ddm.DdmHandleAppName.setAppName("system_process");
try {
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null, this);
**//我们看到了什么 Application这个我们最熟悉不过了,这里Instrumentation会利用反射的方式进行创建,**
Application app = Instrumentation.newApplication(Application.class, context);
mAllApplications.add(app);
mInitialApplication = app;
app.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
最让我们关注还是ActivityManagerService 的attachApplication(mAppThread); 我们看看他又做了什么操作
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
...
thread.bindApplication(processName, appInfo, providers,
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher, testMode,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
if (hr != null && normalMode) {
if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
//这里调用ActivityStack 的realStartActivityLocked 正式开启页面,
if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (Exception e) {
}
} else {
mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
}
}
...
// 这个操作里面主要是这个方法,那我们需要弄明白 IApplicationThread 以及 bindApplication ()做了那些操作。
IApplicationThread
这里我就直接说了,IApplicationThread 其实就是一个接口,那我们最重要的是看他在那里实现的,ActivityThread类中有这么两个关乎生命周期的类 如下
- class ApplicationThread extends ApplicationThreadNative
- class ApplicationThreadNative extends Binder implements IApplicationThread
- class H extends Handler
我们跟着上面的方法进入到 ApplicationThread
public final void bindApplication(String processName,
ApplicationInfo appInfo, List<ProviderInfo> providers,
ComponentName instrumentationName, String profileFile,
ParcelFileDescriptor profileFd, boolean autoStopProfiler,
Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
int debugMode, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo,
Map<String, IBinder> services, Bundle coreSettings) {
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.debugMode = debugMode;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfileFile = profileFile;
data.initProfileFd = profileFd;
data.initAutoStopProfiler = false;
// 最终走到了H
queueOrSendMessage(H.BIND_APPLICATION, data);
}
private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
synchronized (this) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
mH.sendMessage(msg);
}
}
看到这里我们大致可以认为bindApplication 进过了ApplicationThreadNative 以及ApplicationThreadProxy 进入到H 的handleMessage中
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
进入方法
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
mProfiler = new Profiler();
mProfiler.profileFile = data.initProfileFile;
mProfiler.profileFd = data.initProfileFd;
mProfiler.autoStopProfiler = data.initAutoStopProfiler;
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName);
if (data.persistent) {
Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
if (!ActivityManager.isHighEndGfx(display)) {
HardwareRenderer.disable(false);
}
}
if (mProfiler.profileFd != null) {
mProfiler.startProfiling();
}
if (data.appInfo.targetSdkVersion <= 12) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
TimeZone.setDefault(null);
Locale.setDefault(data.config.locale);
applyConfigurationToResourcesLocked(data.config, data.compatInfo);
applyCompatConfiguration();
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
setupGraphicsSupport(data.info);
if ((data.appInfo.flags &
(ApplicationInfo.FLAG_SYSTEM |
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
StrictMode.conditionallyEnableDebugLogging();
}
if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
== 0) {
Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
}
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try {
ProxyProperties proxyProperties = service.getProxy();
Proxy.setHttpProxySystemProperty(proxyProperties);
} catch (RemoteException e) {}
}
if (data.instrumentationName != null) {
ContextImpl appContext = new ContextImpl();
appContext.init(data.info, null, this);
InstrumentationInfo ii = null;
try {
ii = appContext.getPackageManager().
getInstrumentationInfo(data.instrumentationName, 0);
} catch (PackageManager.NameNotFoundException e) {
}
if (ii == null) {
throw new RuntimeException(
"Unable to find instrumentation info for: "
+ data.instrumentationName);
}
mInstrumentationAppDir = ii.sourceDir;
mInstrumentationAppPackage = ii.packageName;
mInstrumentedAppDir = data.info.getAppDir();
ApplicationInfo instrApp = new ApplicationInfo();
instrApp.packageName = ii.packageName;
instrApp.sourceDir = ii.sourceDir;
instrApp.publicSourceDir = ii.publicSourceDir;
instrApp.dataDir = ii.dataDir;
instrApp.nativeLibraryDir = ii.nativeLibraryDir;
LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true);
ContextImpl instrContext = new ContextImpl();
instrContext.init(pi, null, this);
//一下一大堆都是获取mInstrumentation 的操作
try {
java.lang.ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}
mInstrumentation.init(this, instrContext, appContext,
new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
} else {
mInstrumentation = new Instrumentation();
}
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
一堆代码对我们而言重要的就那么几句,看最后callApplicationOnCreate 这里才正式进入了Application的onCreate回调当中,也就是应用入口,我们看到这还没有达到最初的目的,我们要看到Activity是如何创建的啊,现在呢只是看到了Application的创建。 上面提到了 进入到 ActivityStack的realStartActivityLocked方法正式开启Activity,那看看他做了什么
ActivityStack 的 realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
。。。
//重要的在这里,这里的app.thread 当然是ApplicationThread scheduleLaunchActivity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
new Configuration(mService.mConfiguration),
r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
。。。
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profileFile = profileName;
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
updatePendingConfiguration(curConfig);
又是进入到 H的HandleMessage,那么我们很清楚了, H 最大的作用就是消息处理中心,所有的生命周期都在这里进行分发
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
case LAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
unscheduleGcIdler();
if (r.profileFd != null) {
mProfiler.setProfiler(r.profileFile, r.profileFd);
mProfiler.startProfiling();
mProfiler.autoStopProfiler = r.autoStopProfiler;
}
handleConfigurationChanged(null, null);
//我们以前常说的Activity的绘制流程是从这个方法开始的,现在我们看到真面目了,下来的东西已经不属于这里了,ActivityManagerService 于ViewRootImpl 绘制页面了,下节再说了。
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward);
if (!r.activity.mFinished && r.startsNotResumed) {
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
r.state = oldState;
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
}
r.paused = true;
}
} else {
// If there was an error, for any reason, tell the activity
// manager to stop us.
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null);
} catch (RemoteException ex) {
// Ignore
}
}
}
- 到了这里我们已经很清楚了如何开启的Application以及如何开启的页面,来张图作为总结,请原谅我用的别人的。