美文网首页
Android源码解析之(六)Activity启动过程

Android源码解析之(六)Activity启动过程

作者: 01_小小鱼_01 | 来源:发表于2018-06-28 23:39 被阅读28次

Android中,一个应用程序的开始是从ActivityThread.java中的main()方法开始的。

public static void main(String[] args){
    ...
    Looper.prepareMainLooper(); 
    //初始化Looper
    ...
    ActivityThread thread = new ActivityThread();
    //实例化一个ActivityThread
    thread.attach(false);
    //这个方法最后就是为了发送出创建Application的消息
    ... 
    Looper.loop();
    //主线程进入无限循环状态,等待接收消息
}

ActivityThread的attach()方法最终的目的是发送出一条创建Application的消息——H.BIND_APPLICATION,到主线程的主Handler。

final ApplicationThread mAppThread = new ApplicationThread();

public void attach(boolean system){
    ...
    final IActivityManager mgr = ActivityManagerNative.getDefault();  
    //获得IActivityManager实例,下面会看看它是个啥
    try {
        mgr.attachApplication(mAppThread);
         //看见没?关键啊。mAppThread这个参数下面也会说一下
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    ...
}

IActivityManager 是一个接口,调用ActivityManagerNative.getDefault()获得的实际是一个代理类的实例ActivityManagerProxy

public ActivityManagerProxy(IBinder remote) {
        mRemote = remote;
}

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);
    //这个地方调用了构造函数
}

private static final Singleton<IActivityManager> gDefault = 
  new Singleton<IActivityManager>() {
    protected IActivityManager create() {
       IBinder b = ServiceManager.getService("activity");
       //重点啊!IBinder实例就是在这里获得的。
        ...
        IActivityManager am = asInterface(b);
        //调用了上面的方法。
        ...
        return am;
    }
};

接下来看看attachApplication这个方法到底是做了些什么?

final ApplicationThread mAppThread = new ApplicationThread();
public void attachApplication(IApplicationThread app){
  ...
  mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);  
  ...
}

调用了IBinder实例的tansact()方法,并且把参数app放到了data中,最终传递给ActivityManager

IApplicationThread 又是什么东东?通过源码我们可以发现

private class ApplicationThread extends ApplicationThreadNative{
    ...
}

public abstract class ApplicationThreadNative extends Binder 
    implements IApplicationThread{
    ...
    //无参构造函数
    public ApplicationThreadNative() {
        //这是Binder的
        attachInterface(this, descriptor);
    }
    ...
}

public interface IApplicationThread extends IInterface {
    ...
    String descriptor = "android.app.IApplicationThread"; 
    //留意下这个参数
    ...
}

ApplicationThread最终也是一个Binder!同时,由于实现了IApplicationThread接口,所以它也是一个IApplicationThread.

至此为止Binder就和AMS之间保持着通讯了。

ActivityManagerService调度发送初始化消息

AMS里面有一个attachApplicationLocked方法

private final boolean attachApplicationLocked(IApplicationThread thread
, int pid) {
    ...
    thread.bindApplication();
    ...
}

其实,最终也是会调用自己的bindApplication方法,初始化Application信息。

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){
    
    ...
    sendMessage(H.BIND_APPLICATION, data);
}

这个函数里面最重要的就是其实就是发了一条H.BIND_APPLICATION消息,通知主线程初始化Application。

private void handleBindApplication(AppBindData data) {
    ...
    mInstrumentation = (Instrumentation)
        cl.loadClass(data.instrumentationName.getClassName())
        .newInstance();
    //通过反射初始化一个Instrumentation仪表。后面会介绍。
    ...
    Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    //通过LoadedApp命令创建Application实例
    mInitialApplication = app;
    ...
    mInstrumentation.callApplicationOnCreate(app);
    //让仪器调用Application的onCreate()方法
    ...
}

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

更多内容:
Android Activity的启动流程源码解析(8.0)

相关文章

网友评论

      本文标题:Android源码解析之(六)Activity启动过程

      本文链接:https://www.haomeiwen.com/subject/lzgnyftx.html