App啓動(二)AMS在Application創建過程中的調度

上一篇文章中我們說到ActivityThread通過AMS的attachApplication方法將mAppThread對象關聯到了AMS中,並且後面通過mAppThread對Application進行創建、生命週期的管理等。這次我們就研究下它是怎麼做到上述這些的。

首先我們繼續看ActivityThread#attach方法搬過來

public void attach(boolean system){
    ...
    //獲得IActivityManager實例,他是一個ActivityManagerProxy的示例
     final IActivityManager mgr = ActivityManager.getService();
    try {
        //這裏是關鍵。mAppThread是一個ApplicationThread實例,具體的在下面說
        mgr.attachApplication(mAppThread);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    ...
}

我們知道mgr是一個Binder對象,由於是遠程調用,所以它是一個IActivityManager.Stub.Proxy對象

我們來看IActivityManager.Stub.ProxyattachApplication方法

1.IActivityManager.Stub.Proxy#attachApplication

public void attachApplication(IApplicationThread app) throws RemoteException{
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    //把IApplicationThread 的對象app寫到了data裏,
    //app就是mAppThread,mAppThread是什麼看後面分析
    data.writeStrongBinder(app.asBinder());
    //重點在這裏,用mRemote把dare傳輸出去
    mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
    reply.readException();
    data.recycle();
    reply.recycle();
}

這裏用了Binder機制調用通過transact方法調用ATTACH_APPLICATION_TRANSACTION綁定的方法

transact方法爲Binder類的方法,它會調用子類的onTransact方法,我們來看ActivityManagerServiceonTransact方法

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
    if (code == SYSPROPS_TRANSACTION){...}
    try {
        return super.onTransact(code, data, reply, flags);
        } catch (RuntimeException e) {
           ...
        }   
}

這裏實際上是交給了它的父類來處理,而ActivityManagerService的父類是IActivityManager.Stub

IActivityManager.StubonTransact方法源碼

 @Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
    throws RemoteException {
    switch (code){
        case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            //從data裏取出app,也就是之前傳入的mAppThread
            IApplicationThread app = ApplicationThreadNative.asInterface(
                data.readStrongBinder());
            if (app != null) {
                //看這裏,轉到attachApplication去處理了
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }
    }

可以看到他調用當前類的attachApplication方法,實際上就是ActivityManagerServiceattachApplication方法。

實際上上面的IActivityManager.Stub類是根據IActivityManager.aidl自動生成,aidl機制了通過Binder遠程調用相關方法會實際調用遠程對象的同名方法

2. ActivityManagerService#attachApplication

public final void attachApplication(IApplicationThread thread) {
    int callingPid = Binder.getCallingPid();
    ...
    attachApplicationLocked(thread, callingPid);
    ...  
}

attachApplication方法又調用了attachApplicationLocked方法

private final boolean attachApplicationLocked(IApplicationThread thread
, int pid) {
    ...
    //看這裏通過thread調用了bindApplication方法
    thread.bindApplication();
    ...
}

可以看到調用了IApplicationThread類型對象threadbindApplication方法,而這個thread其實就是上一篇文章的mAppThread對象的代理對象,這樣就跟前一篇文章聯繫起來了,AMS通過Binder機制調用ApplicationThreadbindApplication方法創建Application對象。

至此,我們關於AMS在創建Application過程中的調度就分析完了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章