ActivityThread解析之Application与Activity启动

  • 前言

在看ActivityThread源码的时候,看到有博客提到它承担着整个应用的运转以及生命周期。于是很好奇想一探究竟,跟着跟着大概就把应用启动过程过程了解了一下。这篇文章主要是介绍ActivityThread中有关于应用启动过程以及Activity启动部分。有关Binder的机制或者其他部分内容太多了,以后专门看看。

  • 源码分析

Activity有且只有一个ActivityThread对象,他是每一个应用程序所在进程的主线程,。先看看主入口方法main,整个应用的loop死循环是从这边启动的。贴上代码:

public static void main(String[] args) {
	...
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    ...
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

第一部分是ActivityThread对象执行attach方法。这个是本文要分析的部分,就是他来启动应用。

第二部分是启动Looper,这个是整个应用程序的心脏。下一篇文章将分析。

OK!先跟进attach方法看下。贴上代码:

private void attach(boolean system) {
   	if (!system) {
    	final IActivityManager mgr = ActivityManagerNative.getDefault();
     	try {
        	mgr.attachApplication(mAppThread);
     	} catch (RemoteException ex) {
          	throw ex.rethrowFromSystemServer();
     	}
 	} else {
      	...
 	}    
    ...
}

传入system值为false,那么这里会进入判断为true的代码块里面。其中attachApplication是启动Application的方法,也是作为本文分析流程的入口。

1、ActivityThreadmAppThread对象传给AMS

上面介绍到了attachApplication方法,那么接下来看下mAppThread怎么传给AMS的。贴上时序图:

ActivityThread解析之Application与Activity启动

可以看到Activity通过ActivityManagerProxy代理来和AMS通信的。

那么先看下ActivityManagerNative.getDefault()是怎么获取对象的。先进入ActivityManagerNativegetDefault方法,贴上代码:

	/**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

注意到是gDefault对象的方法,跟进去:

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;
        }
    };

public abstract class Singleton<T> {
    private T mInstance;
    protected abstract T create();
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

首先Singleton是一个获取单例对象的方法。首次调用get()方法就会执行create(),那么回到gDefault对象的create()方法看看。

首先是ServiceManager.getService("activity")。跟进ServiceManager类源码看一下:

 private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }   // Find the service manager
    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
    return sServiceManager;
}

/**
 * Returns a reference to a service with the given name.
 * 
 * @param name the name of the service to get
 * @return a reference to the service, or <code>null</code> if the service doesn't exist
 */
public static IBinder getService(String name) {
    try {
        IBinder service = sCache.get(name);
        if (service != null) {
            return service;
        } else {
            return getIServiceManager().getService(name);
        }
    } catch (RemoteException e) {
        Log.e(TAG, "error in getService", e);
    }
    return null;
}

先看下getIServiceManager()方法,他返回的sServiceManager对象(ServiceManagerService的代理)。ServiceManagerService不是真实存在的,而是存在于C++层的一个单独的进程。

那么getService就是通过代理获取String为activity的服务的IBinder对象,其实也就是AMS的IBinder对象。

现在回到gDefault方法中。看下asInterface(b)方法,其中b也就是上面从ServiceManagerService获取的IBinder对象。

现在看下asInterface方法,贴上代码:

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);
}

queryLocalInterface方法用于检查obj是否位于本地进程,很明显前面获取AMS的IBinder对象位于另一个进程。那么asInterface返回的就是new出来的ActivityManagerProxy对象了。

到这一步返回到上面的getDefault()方法,可以知道他实际上返回的是AMS的ActivityManagerProxy代理对象。也就是说attach方法中的mgr对象其实也就是AMS的代理了。

那么看下attach方法中的mgr.attachApplication(mAppThread),也就是通过代理把mAppThread参数传给了AMS。

那到底是传什么东西呢?

看看ActivityManagerProxy源码:

class ActivityManagerProxy implements IActivityManager
{
    ...
    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();
    }
}

先是把app写入data数据,然后传给远程的AMS。然后看下AMS那边的接收代码:

@Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException{
        	...
            case ATTACH_APPLICATION_TRANSACTION: {
            	data.enforceInterface(IActivityManager.descriptor);
            	IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            	if (app != null) {
                	attachApplication(app);
                 }
            	reply.writeNoException();
            	return true;
        }  
}

注意到ApplicationThreadNative.asInterface(data.readStrongBinder()),返回的是ApplicationThread的代理对象。然后再看下attachApplication(app),也就是说AMS这边其实获取到的是传进来的ApplicationThread参数对象的代理。

2、AMS通过mAppThread参数对象创建Application

上面说到mAppThread作为传给了AMS,那么AMS持有该对象并回调bindApplication方法。先看下时序图:

ActivityThread解析之Application与Activity启动

上面讲到ActivityThread通过代理调用了AMS的attachApplication方法。那么AMS这边的attachApplication方法是怎么样的呢?看下源码:

@Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

thread也就是上面提到的ApplicationThread的代理对象applicationThread。重点看下attachApplicationLocked方法,贴上代码:

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid){
                ...
             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            }

也就是说通过这个代理对象执行了bindApplication方法。那么ApplicationThreadProxy是怎么个逻辑呢?

@Override
    public final void bindApplication(String packageName, ApplicationInfo info,
            List<ProviderInfo> providers, ComponentName testName, ProfilerInfo profilerInfo,
            Bundle testArgs, IInstrumentationWatcher testWatcher,
            IUiAutomationConnection uiAutomationConnection, int debugMode,
            boolean enableBinderTracking, boolean trackAllocation, boolean restrictedBackupMode,
            boolean persistent, Configuration config, CompatibilityInfo compatInfo,
            Map<String, IBinder> services, Bundle coreSettings) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        ...
        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }

这个是在AMS里面执行的,也就是把那么一大堆参数存入data中。再调用mRemote.transact传给ActivityThread。那现在看下ActivityThread怎么处理接收到的数据。

case BIND_APPLICATION_TRANSACTION:
{
     data.enforceInterface(IApplicationThread.descriptor);
     ...
     bindApplication(packageName, info, providers, testName, profilerInfo, testArgs,testWatcher, 		uiAutomationConnection, testMode, enableBinderTracking,trackAllocation, 			restrictedBackupMode, persistent, config, compatInfo, services,coreSettings);
     return true;
}

ActivityThread中回调bindApplication方法。因为传过去的是ApplicationThread对象,也就是说调用ApplicationThread中该方法的实现。贴上代码:

public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                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.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            sendMessage(H.BIND_APPLICATION, data);
        }

OK!那就是接收到数据之后,给系统发个Message。系统的Looper接收到信息之后会跳转到handleBindApplication方法中。那么到这边,ActivityThread就开始根据AMS返回回来的信息开始创建应用了。

3、Application的创建以及Activity创建

那么先看下handleBindApplication方法,贴上该方法:

private void handleBindApplication(AppBindData data) {
    ...
    mInstrumentation = (Instrumentation)
        cl.loadClass(data.instrumentationName.getClassName())
        .newInstance();
    ...
    Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    mInitialApplication = app;
    ...
    mInstrumentation.callApplicationOnCreate(app);
    ...
}

首先是利用反射初始化一个mInstrumentation对象出来,后续会经常用到。

data.info是AMS传过来的LoadedApk对象,那么下面看下data.info.makeApplication做了些什么:

public Application makeApplication(boolean forceDefaultAppClass,
    Instrumentation instrumentation) {
    if (mApplication != null) {
            return mApplication;
    }
    ...
    String appClass = mApplicationInfo.className;
    ...
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext);
    ...
}

看下newApplication这个方法:

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;
}

可以看到执行了两个步骤:

1、通过反射新建了一个Application对象

2、app调用attach方法,将appcontext绑定

回到handleBindApplicationmInstrumentation.callApplicationOnCreate(app)方法:

public void callApplicationOnCreate(Application app) {
    app.onCreate();
}

OK!mInstrumentation可以说是一个代理层,最终Apllication的创建,Activity的创建,以及生命周期都会经过这个对象去执行。个人理解这是代理模式的一个典型例子。

当Application初始化完成后,系统会根据Manifests中的配置的来启动对应的Activity。本文对这个过程不做介绍,先说下处于ActicityThread部分。当启动Activity之后,ActivityThred的H就收到了一条LAUNCH_ACTIVITY。接收到该Message之后,便会调用到handleLaunchActivity方法:

private void handleLaunchActivity(ActivityClientRecord r
    , Intent customIntent
    , String reason) {
    ...
    Activity a = performLaunchActivity(r, customIntent);
    ...
    if (a != null) {
        ...
        handleResumeActivity(r.token
        , false
        , r.isForward
        ,!r.activity.mFinished && !r.startsNotResumed
        , r.lastProcessedSeq, reason);
        ...
    }
}

首先看下performLaunchActivity代码:

private Activity performLaunchActivity(ActivityClientRecord r
    , Intent customIntent) {
    ...
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    ...
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    ...
    activity.attach(appContext
        , this
        , getInstrumentation()
        , r.token
        ,.ident
        , app
        , r.intent
        , r.activityInfo
        , title
        , r.parent
        , r.embeddedID
        , r.lastNonConfigurationInstances
        , config
        ,r.referrer
        , r.voiceInteractor
        , window);
    ...
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    ...
}

先看下mInstrumentation.newActivity。可以看到Activity也交由mInstrumentation代理了,下面是代码。

public Activity newActivity(ClassLoader cl, String className,Intent intent)
            throws InstantiationException, IllegalAccessException,ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
}

创建Activity其实也是通过反射直接new出来的。

再看下callActivityOnCreate方法,也是交给mInstrumentation处理。他最终会调用Activity的两个方法:

final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
}

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    restoreHasCurrentPermissionRequest(icicle);
    onCreate(icicle, persistentState);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

这也就是Activity的oncreate生命周期,至此Activity也跑起来了。

  • 后续任务

1、应用的启动过程还涉及到很多东西,比如说Manifest解析,Binder机制等等。可以逐渐了解。