当你在手机上安装一个app应用后,只要点击手机桌面上的app图标就可以开启这个应用,虽然这个操作很简单,但你知道它的实现原理吗?如果你是一位纯应用的app应用开发者,可能你根本不会去了解它是怎么实现的,因为你关注的只是app。如果你比较熟悉了,此博文略过哈。今天我们就一起来学习下app是如何在安卓系统中启动起来的?
一、初步分析
我们的app应用安装在手机后在手机桌面上会有一个图标,这个图标就是app的启动图标。其实手机桌面,稍微对framework层代码有过接触的人都知道,它对应的就是Lanucher模块,说明启动app应用的起始点就是在Launcher。至于Launcher,它的代码量有点多,这里就不一一介绍了,这不是此博文的重点。Java代码有个类方法入口:public static void main(String [] args); 我们的app启动也有个类方法入口,那就是ActivityThread类,它里面也有个:
public static void main(String[] args)
这跟java入口方法一模一样,接下来我们一起分析下:
二、ActivityThread类
我们先把main方法的代码贴一下:
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(newActivityThread.EventLoggingReporter(null));
Security.addProvider(newAndroidKeyStoreProvider());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = newActivityThread();
thread.attach(false);
if(sMainThreadHandler == null) {
sMainThreadHandler =thread.getHandler();
}
AsyncTask.init();
Looper.loop();
throw new RuntimeException("Mainthread loop unexpectedly exited");
}
这句代码Looper.prepareMainLooper();可以看出为什么在主线程创建Handler不用调用Looper.prepare();方法,因为它默认已经调用了。接着往下走,ActivityThread thread = new ActivityThread();它实例化了一个ActivityThread对象,然后调用thread.attach(false);这句代码是关键,我们进入attach方法:
private void attach(boolean system) {
sCurrentActivityThread = this;
this.mSystemThread = system;
if(!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
public void run() {
ActivityThread.this.ensureJitEnabled();
}
});
DdmHandleAppName.setAppName("<pre-initialized>",UserHandle.myUserId());
RuntimeInit.setApplicationObject(this.mAppThread.asBinder());
IActivityManager e =ActivityManagerNative.getDefault();
try {
e.attachApplication(this.mAppThread);
} catch (RemoteException var5) {
;
}
} else {
DdmHandleAppName.setAppName("system_process",UserHandle.myUserId());
try {
this.mInstrumentation = newInstrumentation();
ContextImpl e1 =ContextImpl.createAppContext(this, this.getSystemContext().mPackageInfo);
Application app =Instrumentation.newApplication(Application.class, e1);
this.mAllApplications.add(app);
this.mInitialApplication =app;
app.onCreate();
} catch (Exception var4) {
throw newRuntimeException("Unable to instantiate Application():" +var4.toString(), var4);
}
}
DropBox.setReporter(newActivityThread.DropBoxReporter());
ViewRootImpl.addConfigCallback(newComponentCallbacks2() {
public voidonConfigurationChanged(Configuration newConfig) {
synchronized(ActivityThread.this.mResourcesManager) {
if(ActivityThread.this.mResourcesManager.applyConfigurationToResourcesLocked(newConfig,(CompatibilityInfo)null) && (ActivityThread.this.mPendingConfiguration== null ||ActivityThread.this.mPendingConfiguration.isOtherSeqNewer(newConfig))) {
ActivityThread.this.mPendingConfiguration = newConfig;
ActivityThread.this.sendMessage(118, newConfig);
}
}
}
public void onLowMemory() {
}
public void onTrimMemory(intlevel) {
}
});
}
方法里分应用app和系统app,我们这里只分析应用的app,有兴趣的同学可以自己去研究哈。
IActivityManager e =ActivityManagerNative.getDefault(); 创建IActivityManager e对象,这个对象是通过ActivityManagerNative类里的getDefault方法获取的,我们进入到ActivityManagerNative类:
public static IActivityManagergetDefault() {
return(IActivityManager)gDefault.get();
}
这里通过gDefault的get()方法返回IActivityManager对象,再来看下gDefault是何方神圣。我们找到代码:
private static finalSingleton<IActivityManager> gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am =ActivityManagerNative.asInterface(b);
return am;
}
};
这里利用了Binder机制来创建IActivityManager,其中ServiceManager其实它的实现就是ActivityManagerService,以下简称AMS,它是android系统一种重要的服务。我们回到上面的attach()方法:
IActivityManager e =ActivityManagerNative.getDefault();
try {
e.attachApplication(this.mAppThread);
} catch (RemoteException var5) {
;
}
获取到IActivityManager对象后,调用了e.attachApplication(this.mAppThread);方法,IActivityManager的attachApplication方法也是在AMS中实现的,我们进入AMS中的这个方法:
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid =Binder.getCallingPid();
final long origId =Binder.clearCallingIdentity();
attachApplicationLocked(thread,callingPid);
Binder.restoreCallingIdentity(origId);
}
}
attachApplication方法中又调用了attachApplicationLocked(thread,callingPid);再进入这个方法瞧一睢:
private final booleanattachApplicationLocked(IApplicationThread thread,
int pid) {
…………
// See if the top visible activity iswaiting to run in this process...
if (normalMode) {
try {
if(mStackSupervisor.attachApplicationLocked(app, mHeadless)) {
didSomething = true;
}
} catch (Exception e) {
badApp = true;
}
}
// Find any services that should berunning in this process...
if (!badApp) {
try {
didSomething |=mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
…………
return true;
}
我们简化了attachApplicationLocked代码,如上图。从上面代码我们很容易看出它又调用了mStackSupervisor.attachApplicationLocked(app, mHeadless);这个mStackSupervisor是何方神圣呢?继续追踪代码,发现它是ActivityStackSupervisor对象,然后我们进入ActivityStackSupervisor类找到对应的attachApplicationLocked方法,代码如下:
booleanattachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
boolean didSomething = false;
final String processName =app.processName;
for (int stackNdx = mStacks.size() -1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack =mStacks.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 {
if (headless) {
Slog.e(TAG,"Starting activities not supported on headless device: "
+ hr);
} else 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;
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0);
}
return didSomething;
}
attachApplicationLocked方法代码比较简单,但我们还是抓重点,我们会看到这个realStartActivityLocked(hr, app, true, true);真正的逻辑就在这里,我们继续追踪:
final boolean realStartActivityLocked(ActivityRecordr,
ProcessRecord app, booleanandResume, boolean checkConfig)
throws RemoteException {
…………
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
app.thread.scheduleLaunchActivity(newIntent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
newConfiguration(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-weightprocess! Note that the package
// manager will ensure thatonly activity can run in the main
// process of the .apk, whichis 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
+ " whenalready running "
+ mService.mHeavyWeightProcess);
}
mService.mHeavyWeightProcess = app;
Message msg =mService.mHandler.obtainMessage(
ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
msg.obj = r;
mService.mHandler.sendMessage(msg);
}
}
…………
return true;
}
定位到核心代码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);这里调用了app.thread的scheduleLaunchActivity方法,这里app.thread是啥呢?我们继续追踪,其实它就是ActivityThread,很高兴我们又回到了起始的地方,从哪里来回哪里去,哈哈,别开小差,继续看代码,我们找到了ActivityThread里的scheduleLaunchActivity方法,代码如下:
public final voidscheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfoinfo, Configuration curConfig, CompatibilityInfo compatInfo, int procState,Bundle state, List<ResultInfo> pendingResults, List<Intent>pendingNewIntents, boolean notResumed, boolean isForward, String profileName,ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
this.updateProcessState(procState,false);
ActivityThread.ActivityClientRecord r= new ActivityThread.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;
this.updatePendingConfiguration(curConfig);
ActivityThread.this.sendMessage(100,r);
}
我们看到最后一行代码:ActivityThread.this.sendMessage(100, r);这里发送了一个消息,我们继续追踪:
private void sendMessage(int what, Objectobj) {
this.sendMessage(what, obj, 0, 0,false);
}
继续看sendMessage方法代码:
private void sendMessage(int what, Objectobj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if(async) {
msg.setAsynchronous(true);
}
this.mH.sendMessage(msg);
}
最后一行代码是重点:this.mH.sendMessage(msg);我们找到接收的地方,直接上代码:
case 100:
Trace.traceBegin(64L,"activityStart");
data =(ActivityThread.ActivityClientRecord)msg.obj;
data.packageInfo =ActivityThread.this.getPackageInfoNoCheck(data.activityInfo.applicationInfo,data.compatInfo);
ActivityThread.this.handleLaunchActivity(data, (Intent)null);
Trace.traceEnd(64L);
break;
这里我们主要看ActivityThread.this.handleLaunchActivity(data, (Intent)null);这句代码,继续看代码:
private void handleLaunchActivity(ActivityThread.ActivityClientRecordr, Intent customIntent) {
this.unscheduleGcIdler();
if(r.profileFd != null) {
this.mProfiler.setProfiler(r.profileFile, r.profileFd);
this.mProfiler.startProfiling();
this.mProfiler.autoStopProfiler =r.autoStopProfiler;
}
this.handleConfigurationChanged((Configuration)null,(CompatibilityInfo)null);
Activity a =this.performLaunchActivity(r, customIntent);
if(a == null) {
try {
ActivityManagerNative.getDefault().finishActivity(r.token,0, (Intent)null);
} catch (RemoteException var6) {
;
}
} else {
r.createdConfig = newConfiguration(this.mConfiguration);
Bundle ex = r.state;
this.handleResumeActivity(r.token,false, r.isForward, !r.activity.mFinished && !r.startsNotResumed);
if(!r.activity.mFinished&& r.startsNotResumed) {
try {
r.activity.mCalled =false;
this.mInstrumentation.callActivityOnPause(r.activity);
if(r.isPreHoneycomb()) {
r.state = ex;
}
if(!r.activity.mCalled) {
throw newSuperNotCalledException("Activity " + r.intent.getComponent().toShortString()+ " did not call through to super.onPause()");
}
} catch(SuperNotCalledException var7) {
throw var7;
} catch (Exception var8) {
if(!this.mInstrumentation.onException(r.activity, var8)) {
throw newRuntimeException("Unable to pause activity " +r.intent.getComponent().toShortString() + ": " + var8.toString(),var8);
}
}
r.paused = true;
}
}
}
我们找到这行代码:Activity a = this.performLaunchActivity(r, customIntent);这里又调用了performLaunchActivity(r,customIntent);方法,其代码如下:
private ActivityperformLaunchActivity(ActivityThread.ActivityClientRecord r, IntentcustomIntent) {
ActivityInfo aInfo = r.activityInfo;
if(r.packageInfo == null) {
r.packageInfo =this.getPackageInfo((ApplicationInfo)aInfo.applicationInfo, r.compatInfo, 1);
}
ComponentName component =r.intent.getComponent();
if(component == null) {
component = r.intent.resolveActivity(this.mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if(r.activityInfo.targetActivity !=null) {
component = newComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity);
}
Activity activity = null;
try {
ClassLoader e =r.packageInfo.getClassLoader();
activity =this.mInstrumentation.newActivity(e, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(e);
if(r.state != null) {
r.state.setClassLoader(e);
}
} catch (Exception var13) {
if(!this.mInstrumentation.onException(activity, var13)) {
throw new RuntimeException("Unableto instantiate activity " + component + ": " + var13.toString(),var13);
}
}
try {
Application e1 =r.packageInfo.makeApplication(false, this.mInstrumentation);
if(activity != null) {
Context appContext =this.createBaseContextForActivity(r, activity);
CharSequence title =r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = newConfiguration(this.mCompatConfiguration);
activity.attach(appContext,this, this.getInstrumentation(), r.token, r.ident, e1, r.intent,r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances,config);
if(customIntent != null) {
activity.mIntent =customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity =false;
int theme =r.activityInfo.getThemeResource();
if(theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
this.mInstrumentation.callActivityOnCreate(activity, r.state);
if(!activity.mCalled) {
throw newSuperNotCalledException("Activity " +r.intent.getComponent().toShortString() + " did not call through tosuper.onCreate()");
}
r.activity = activity;
r.stopped = true;
if(!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if(!r.activity.mFinished&& r.state != null) {
this.mInstrumentation.callActivityOnRestoreInstanceState(activity,r.state);
}
if(!r.activity.mFinished) {
activity.mCalled = false;
this.mInstrumentation.callActivityOnPostCreate(activity, r.state);
if(!activity.mCalled) {
throw newSuperNotCalledException("Activity " +r.intent.getComponent().toShortString() + " did not call through tosuper.onPostCreate()");
}
}
}
r.paused = true;
this.mActivities.put(r.token, r);
} catch (SuperNotCalledExceptionvar11) {
throw var11;
} catch (Exception var12) {
if(!this.mInstrumentation.onException(activity,var12)) {
throw newRuntimeException("Unable to start activity " + component + ":" + var12.toString(), var12);
}
}
return activity;
}
我们找到其中的关键代码:
try { ClassLoader e = r.packageInfo.getClassLoader(); activity = this.mInstrumentation.newActivity(e, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(e); if(r.state != null) { r.state.setClassLoader(e); } } catch (Exception var13) { if(!this.mInstrumentation.onException(activity, var13)) { throw new RuntimeException("Unable to instantiate activity " + component + ": " + var13.toString(), var13); } }
这里的关键代码是:
activity = this.mInstrumentation.newActivity(e, component.getClassName(), r.intent);
从代码中可以看出它调用了mInstrumentation的newActivity(e, component.getClassName(), r.intent);方法,其代码如下:
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Activity)cl.loadClass(className).newInstance(); }
它返回了一个实例对象,其他的什么也没做,我们回到ActivityThread的performLaunchActivity方法,继续往下跟踪代码,发现有一行代码:
this.mInstrumentation.callActivityOnCreate(activity, r.state);
到这里你是否看到了一点点希望之光,这跟Activity的生命周期方法onCreate方法很像,接着再看callActivityOnCreate代码:
public void callActivityOnCreate(Activity activity, Bundle icicle) { Object var3; int N; int i; if(this.mWaitingActivities != null) { var3 = this.mSync; synchronized(this.mSync) { N = this.mWaitingActivities.size(); for(i = 0; i < N; ++i) { Instrumentation.ActivityWaiter am = (Instrumentation.ActivityWaiter)this.mWaitingActivities.get(i); Intent intent = am.intent; if(intent.filterEquals(activity.getIntent())) { am.activity = activity; this.mMessageQueue.addIdleHandler(new Instrumentation.ActivityGoing(am)); } } } } activity.performCreate(icicle); if(this.mActivityMonitors != null) { var3 = this.mSync; synchronized(this.mSync) { N = this.mActivityMonitors.size(); for(i = 0; i < N; ++i) { Instrumentation.ActivityMonitor var12 = (Instrumentation.ActivityMonitor)this.mActivityMonitors.get(i); var12.match(activity, activity, activity.getIntent()); } } } }
从方法代码里我们看出有这样一行代码activity.performCreate(icicle);这里调用了performCreate方法,performCreate方法代码如下:
final void performCreate(Bundle icicle) { this.onCreate(icicle); this.mVisibleFromClient = !this.mWindow.getWindowStyle().getBoolean(10, false); this.mFragments.dispatchActivityCreated(); }
this.onCreate(icicle);这个就是我们要找的方法了,它就是回调activity的onCreate生命周期方法。
app启动流程就分析到这了,不好的地方请大家批评指正。