概述
本文主要通过app启动后,分析系统源码的方式来讲解activity启动,本文占时不讲Binder机制
ps:下次有空会学习并且写下Binder机制,况且我的glide源码还没有写完。本人水平有限,欢迎有老司机过来飙车,指教!
本文涉及以下几个源码:
- ActivityThread
- ActivityManagerNative
- ActivityManagerService
- ActivityStackSupervisor
- Instrumentation
- Activity
上面的源码可以通过:
自己的sdk找到 路径大致为:G:developsoftandroidsdk_assources
或者通过系统源码下载 这篇文章的网站去下载相关的代码
ok,我们首先来回顾一下,在java中 ,我们要运行一个类,肯定会有一个主函数的入口,那么android也是一样的。
正式开车:
我们根据一个调用的时序图来深入简出的分析代码:
上图;
图片太大了,还不知道怎么截成一张整图,有经验老司机,请留意指教。
好了,我们来看 ActivityThread
这里只看关键的代码:
//主函数的入口函数
public static void main(String[] args) {
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
//初始化主线程的Looper
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
//Looper开始轮询
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
看这个方法 thread.attach(false);删除其他的方法,我们只留关键的代码。
private void attach(boolean system) {
//判断是否是系统应用
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//非系统应用
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//2、调用 ActivityManagerNative.getDefault();
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//7. mgr.attachApplication(mAppThread);
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
}
}
}
});
} else {
//系统应用
}
// add dropbox logging to libcore
DropBox.setReporter(new DropBoxReporter());
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
执行到 IActivityManager mgr = ActivityManagerNative.getDefault(); 这个方法,我们看看这个方法返回了什么?
我们来到:ActivityManagerNative
/**
* Retrieve the system's default/global activity manager.
*/
//3、调用IActivityManager getDefault()
static public IActivityManager getDefault() {
return gDefault.get();
}
接着调用:
//4、
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
//4、谁返回来的?
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;
}
};
这样就关联上了ActivityManagerService 我们看这句代码 IBinder b = ServiceManager.getService(“activity”); 那么我们去ActivityManagerService 是什么时候add进去的?我们继续往下看
public static void setSystemProcess() {
try {
ActivityManagerService m = mSelf;
//5、添加进去
ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(m));
ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
ServiceManager.addService("dbinfo", new DbBinder(m));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(m));
}
ServiceManager.addService("permission", new PermissionController(m));
}
我们接着回到 ActivityThread 找到 mgr.attachApplication(mAppThread);
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//2、调用 ActivityManagerNative.getDefault();
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//7. mgr.attachApplication(mAppThread);
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
就是调用ActivityManagerService 里的 attachApplication(IApplicationThread thread)方法
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
//我们注意这个方法 attachApplicationLocked(thread, callingPid);
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
我们来看下 attachApplicationLocked(thread, callingPid); 我只看一些关键的方法
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
//10 attachApplicationLocked(app, mHeadless)
if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) {
didSomething = true;
}
} catch (Exception e) {
badApp = true;
}
}
// Find any services that should be running in this process...
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
// Check if a next-broadcast receiver is in this process...
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
// If the app died trying to launch the receiver we declare it 'bad'
badApp = true;
}
}
return true;
}
这就进入一个关键类了 ActivityStackSupervisor 我们看这个方法mStackSupervisor.attachApplicationLocked(app, mHeadless)
这里由于版本不一样,有的版本参数是2个,有的是一个,忽略这些细节,如果费用纠结这些细节的话,请一定要下载版本一直的源码,这里我就偷个懒,不下载了。
我们来看看ActivityStackSupervisor 这个类
boolean attachApplicationLocked(ProcessRecord app) throws Exception {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFrontStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
//看这个方法的名字就能猜到干啥的了, realStartActivityLocked()
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (Exception e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
我们来看看 ActivityStackSupervisor 里的 realStartActivityLocked()都做了啥?
//9真正的启动
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), r.compat,
app.repProcState, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
// This may be a heavy-weight process! Note that the package
// manager will ensure that only activity can run in the main
// process of the .apk, which is the only thing that will be
// considered heavy-weight.
if (app.processName.equals(app.info.packageName)) {
if (mService.mHeavyWeightProcess != null
&& mService.mHeavyWeightProcess != app) {
Slog.w(TAG, "Starting new heavy weight process " + app
+ " when already running "
+ mService.mHeavyWeightProcess);
}
mService.mHeavyWeightProcess = app;
Message msg = mService.mHandler.obtainMessage(
ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
msg.obj = r;
mService.mHandler.sendMessage(msg);
}
}
} catch (RemoteException e) {
if (r.launchFailed) {
// This is the second time we failed -- finish activity
// and give up.
Slog.e(TAG, "Second failure launching "
+ r.intent.getComponent().flattenToShortString()
+ ", giving up", e);
mService.appDiedLocked(app, app.pid, app.thread);
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash", false);
return false;
}
// This is the first time we failed -- restart process and
// retry.
app.activities.remove(r);
throw e;
}
return true;
}
我们来看上面的这个方法 app.thread.scheduleLaunchActivity( ) app.thread又回到了ActivityThread类中,我们看看这个方法有些什么
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
//看到这里感觉熟悉了吧,发送了一个消息我们来找找看
sendMessage(H.LAUNCH_ACTIVITY, r);
}
我们在handleMessage(Message msg) 中找到了 handleLaunchActivity(r, null);
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);
//通过handle启动activity
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
接着源码继续看 handleLaunchActivity(ActivityClientRecord r, Intent customIntent)
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
//执行启动
Activity a = performLaunchActivity(r, customIntent);
} 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, false);
} catch (RemoteException ex) {
// Ignore
}
}
}
我们看到 通过反射的方式 mInstrumentation.newActivity( cl, component.getClassName(), r.intent);创建了一个 Activity。 好了,到了我们今天最后的一个类,也是最重要的一个类了,希望你坚持看下去:mInstrumentation 代表的就是 Instrumentation
rivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
Activity activity = null;
//反射创建一个Activity
try {
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);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
我们来看看Instrumentation 他是如何创建一个activity的
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
我们在回 ActivityThread 看看 mInstrumentation 都调用哪些方法?
mInstrumentation.callActivityOnDestroy(r.activity);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,r.persistentState);
mInstrumentation.callActivityOnDestroy(r.activity);
mInstrumentation.callActivityOnPause(r.activity);
mInstrumentation.callActivityOnUserLeaving(r.activity);
~~~~~~~~~~~~~~~~~~~~~~~~~等等 剩下方法 童靴你自己找下吧
我们来举例看一个 mInstrumentation.callActivityOnPause(r.activity); 里面它是怎么实现的?
我们在 Instrumentation 发现 是调用 activity.performPause();
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
那我们在去activity的源码一探究竟。
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}
果然有这个方法,并且 onPause();的生命周期方法也在里面。
不知道,你们明白了么? 欢迎老司机指教!
最后
以上就是自觉面包为你收集整理的app( activity) 启动流程的全部内容,希望文章能够帮你解决app( activity) 启动流程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复