Android应用程序入口源码解析,我们在写C、C++或java应用时,都会有一个main函数,但Android的main函数在哪里呢?偶记得从第一个HelloWorld应用开始,就知道,只要在AndroidManifest配置表中对Activity的intent-filter进行配置,action为android.intent.action.MAIN,category为android.intent.category.LAUNCHER,应用程序启动的时候就会首先启动这个Activity,此Activity也就是应用的入口;后来又知道Application这个类,只要有类继承Application,并在AndroidManifest配置表中对application的name进行配置该类,android应用启动后会把该类的attachBaseContext和onCreate方法作为程序开发入口。实际上是不是这样的呢?本篇博文将会从源码角度来分析。
在说Android应用程序开发入口之前,我们有必要了解一下android系统的启动和Android应用程序的启动流程,这样有助于我们对Android系统有一个整体的认识。首先,让我们来简单了解一下Android系统的启动流程。
一、Android系统的启动
Android系统的启动流程图:

根据图,我们知Android启动流程的步骤如下:
1.启动电源
当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。
2.引导程序BootLoader执行
引导程序BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
3.Linux内核启动
内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找init.rc文件,并启动init进程。
4.init进程启动
初始化和启动属性服务,并且启动Zygote进程。
5.Zygote进程启动
创建JavaVM并为JavaVM注册JNI,创建服务端Socket,启动SystemServer进程。
6.SystemServer进程启动
启动Binder线程池和SystemServiceManager,并且启动各种系统服务,例如:ActivityManagerService、PowerManagerService、PackageManagerService,BatteryService、UsageStatsService等其他80多个系统服务。
7.Launcher启动
被SystemServer进程启动的ActivityManagerService会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。
二、Android应用程序启动
上面说到,当Android系统启动完成之后,Lancher也就启动完成了,在我们的桌面上就会看到已安装的应用快捷图标。点击快捷图标,就能启动我们的应用程序。我们知道,android系统中的每一个应用程序,都是独立运行在自己的进程中的,所以在点击应用快捷图标后,如果应用程序还没有进程,首先应该会先建立应用程序的进程。具体流程是怎样的呢?我们先来看流程图:

从流程图知,应用程序在没有创建进程的情况下,会通过ActivitServiceManager去请求服务端Socket,服务端Socket再去请求Zygote进程,让其帮忙建立进程,而Zygote进程会fork自身来创建应用程序进程。应用程序进程创建的同时,应用程序的主线程也会创建,与主线程息息相关的ActivityThread类也会创建,并调用自身的main方法,进行相关的初始化。
具体进程是怎么创建的,这里也还是推荐大神刘望舒的两篇文章,其中非常详细的分析了应用进程的创建过程,想了解的可以看一下。
好了,下面我们继续说是ActivityThread的main方法,也即Android应用程序的入口。
三、Android应用程序入口源码分析
通过Android应用程序的启动,我们知道android应用程序的入口,即ActivityThread的main方法。但在我们开发的时候,很少接触ActivityThread类,主要还是Application和Activity,他俩与ActivityThread的关系怎样呢?让我们从源码中来看看,ActivityThread的main方法:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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 );
Process.setArgV0( "<pre-initialized>" );
Looper.prepareMainLooper(); //1.Looper的创建
if (sMainThreadHandler == null ) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread(); //2.ActivityThread初始化
thread.attach( false ); //3.调用ActivityThread附属方法attach
AsyncTask.init();
if ( false ) {
Looper.myLooper().setMessageLogging( new
LogPrinter(Log.DEBUG, "ActivityThread" ));
}
Looper.loop(); //4.Looper消息开始循环
throw new RuntimeException( "Main thread loop unexpectedly exited" );
}</pre-initialized>
|
在main方法中,Looper的创建和循环,主要与Android的消息机制有关,关于消息机制,我已写过一个篇文章为Android消息机制源码解析(Handler),想了解的可以看一下。这里我们主要来看一下ActivityThread的初始化和attach方法,其中ActivityThread初始化构造方法什么也没做,没啥好看的,我们主要来看看attach方法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
private void attach( boolean system) {
sThreadLocal.set( this );
mSystemThread = system;
if (!system) { //false,不是system,普通app
.......省略
android.ddm.DdmHandleAppName.setAppName( "<pre-initialized>" );
RuntimeInit.setApplicationObject(mAppThread.asBinder());
IActivityManager mgr = ActivityManagerNative.getDefault(); //1.核心代码
try {
mgr.attachApplication(mAppThread); //2.核心代码
} catch (RemoteException ex) {
// Ignore
}
} else { //true,是system
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName( "system_process" );
try {
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null , this );
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);
}
}
......省略
}</pre-initialized>
|
ActivityThread调用attach()传入的参数是false,不是system。注释1通过静态方法ActivityManagerNative.getDefault()获取IActivityManager,实际上是获取到ActivityManagerProxy类,让我们来看ActivityManagerNative.getDefault()方法,进入ActivityManagerNative类
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*/
static public IActivityManager asInterface(IBinder obj) {
if (obj == null ) {
return null ;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null ) {
return in;
}
return new ActivityManagerProxy(obj); //核心方法
}
/**
* Retrieve the system's default/global activity manager.
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<iactivitymanager> gDefault = new Singleton<iactivitymanager>() {
protected IActivityManager create() {
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;
}
};</iactivitymanager></iactivitymanager>
|
通过查看ActivityManagerProxy类,了解到它实现IActivityManager接口,mgr就是ActivityManagerProxy。知道返回的类后,我们再来看一**释2,mgr.attachApplication(mAppThread),其中mAppThread为ApplicationThread,让我们再进入ActivityManagerProxy,看看attachApplication方法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
class ActivityManagerProxy implements IActivityManager
{
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
public IBinder asBinder()
{
return mRemote;
}
.......
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0 ); //核心代码
reply.readException();
data.recycle();
reply.recycle();
}
.......
}
|
从源码中,了解到mRemote是一个IBinder,通过Binder实现进程间通信(Android核心进程通信方法),从而调用到ActivityServiceManager里面对应的方法
?
1
2
3
4
5
6
7
8
|
public final void attachApplication(IApplicationThread thread) {
synchronized ( this ) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid); //核心方法
Binder.restoreCallingIdentity(origId);
}
}
|
我们来继续看方法attachApplicationLocked()
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
.......
thread.bindApplication(processName, appInfo, providers,
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher, testMode,
enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false , true );
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
.....
return true ;
}
|
在attachApplicationLocked()方法中,细节比较多,我们省略掉了,主要来看一下核心方法bindApplication(),其中thread就是ActivityThread中ApplicationThread类,让我们再来看ApplicationThread中的bindApplication()方法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
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 enableOpenGlTrace, boolean isRestrictedBackupMode,
boolean persistent, Configuration config, CompatibilityInfo compatInfo,
Map<string, ibinder= "" > services, Bundle coreSettings) {
if (services != null ) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(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.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfileFile = profileFile;
data.initProfileFd = profileFd;
data.initAutoStopProfiler = false ;
queueOrSendMessage(H.BIND_APPLICATION, data); //核心方法
}</string,></providerinfo>
|
其中queueOrSendMessage方法主要就是向Handler发送了一个Message,让我们来看看具体的方法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// if the thread hasn't started yet, we don't have the handler, so just
// save the messages until we're ready.
private void queueOrSendMessage( int what, Object obj) {
queueOrSendMessage(what, obj, 0 , 0 );
}
private void queueOrSendMessage( int what, Object obj, int arg1) {
queueOrSendMessage(what, obj, arg1, 0 );
}
private void queueOrSendMessage( int what, Object obj, int arg1, int arg2) {
synchronized ( this ) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
mH.sendMessage(msg);
}
}
|
容易知道,主要就是向Handler mH中发送一条消息,根据Handler消息循环机制,可以在handMessage查看处理方法,根据H.BIND_APPLICATION
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
private class H extends Handler {
.....
public static final int BIND_APPLICATION = 110 ;
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
.......
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication" );
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data); //核心方法
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break ;
.......
}
}
|
继续看handleBindApplication()方法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
private void handleBindApplication(AppBindData data) {
try {
.........
Application app = data.info.makeApplication(data.restrictedBackupMode, null );
mInitialApplication = app;
......
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
}
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) { }
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
|
通过分析知data为AppBindData,data.info是一个LoadeApk对象。data.info.makeApplication(),让我们继续看LoadeApk中的方法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
public Application makeApplication( boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null ) {
return mApplication;
}
Application app = null ;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null )) {
appClass = "android.app.Application" ;
}
try {
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext = new ContextImpl();
appContext.init( this , null , mActivityThread);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext); //1.核心方法
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null ) {
try {
instrumentation.callApplicationOnCreate(app); //2.核心方法
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
return app;
}
|
主要还是调ActivityThread中mInstrumentation.newApplication()方法,并传入了继承Application的类的类名appClass,当Applicaiton建立后,马上就调用了方法2即Application的onCreate(),让我们先来看Instrumentation中的newApplication()方法
?
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<!--?--> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context); //方法
return app;
}
|
到这里,就建立了应用程序的Application,然而在Application中那个方法是最先调用的呢?让我们继续看一下
?
1
2
3
4
5
6
7
|
/**
* @hide
*/
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
|
由此我们知道Application初始化后,首先调用的是attachBaseContext()方法,其次才是Application的onCreate方法,让我们看一下调用onCreate()方法,在前面的makeApplication()方法中,有此代码instrumentation.callApplicationOnCreate(app),我们继续来看看源码
?
1
2
3
|
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
|
到这里Android应用程序的入口源码就分析完了。
注:源码采用android-4.1.1_r1版本,建议下载源码然后自己走一遍流程,这样更能加深理解。
四、总结
Android应用程序的入口是ActivityThread的main方法,而Android应用程序的开发入口是Application的attachBaseContext()和onCreate()。如果有类继承Application,并在Androidmanifest中配置了,它就会优先启动。在继承Application类初始化后,首先调用的是attachBaseContext()方法,其次才是onCreate方法。