基於Andoird 4.2.2的Account Manager源代碼分析學習:AccountManager的簡要工作流程

– 對於帳號管理,由接口IAccountManager描述其相關的一組行為
– AccountManagerService是Android的系統服務。它實現瞭接口IAccountManager定義的這一組行為。這些行為的實現依賴應用程序中定義的Authenticator。

– AccountManager是一個面向應用程序開發的組件。它提供一組對應於IAccountManager協議的應用程序接口。這組接口通過Binder機制與系統服務AccountManagerService進行通信,協作完成帳戶相關的操作。同時,AccountManager接收應用程序提供的回調,以此在帳號操作完成之後向應用程序返回對應的結果,同時觸發應用程序層對這個結果的處理。

 

以addAccount()操作為例,步驟如下:

1. AccountManager初始化一個匿名的AmsTask子類實例。AmsTask是AccountManager的內部類:

 

[java]  private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> { 
    final IAccountManagerResponse mResponse; 
    final Handler mHandler; 
    final AccountManagerCallback<Bundle> mCallback; 
    final Activity mActivity; 
    public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) { 
        super(new Callable<Bundle>() { 
            public Bundle call() throws Exception { 
                throw new IllegalStateException("this should never be called"); 
            } 
        }); 
 
        mHandler = handler; 
        mCallback = callback; 
        mActivity = activity; 
        mResponse = new Response(); 
    } 
    … 

    private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
        final IAccountManagerResponse mResponse;
        final Handler mHandler;
        final AccountManagerCallback<Bundle> mCallback;
        final Activity mActivity;
        public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) {
            super(new Callable<Bundle>() {
                public Bundle call() throws Exception {
                    throw new IllegalStateException("this should never be called");
                }
            });

            mHandler = handler;
            mCallback = callback;
            mActivity = activity;
            mResponse = new Response();
        }
        …
它是一個FutureTask子類,執行異步的任務,並返回結果。
addAccount()中的匿名子類實現瞭AmsTask.doWork()方法:

 

[java] public AccountManagerFuture<Bundle> addAccount(final String accountType, 
        final String authTokenType, final String[] requiredFeatures, 
        final Bundle addAccountOptions, 
        final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) { 
    … 
    return new AmsTask(activity, handler, callback) { 
        public void doWork() throws RemoteException { 
            mService.addAcount(mResponse, accountType, authTokenType, 
                    requiredFeatures, activity != null, optionsIn); 
        } 
    }.start(); 

    public AccountManagerFuture<Bundle> addAccount(final String accountType,
            final String authTokenType, final String[] requiredFeatures,
            final Bundle addAccountOptions,
            final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
        …
        return new AmsTask(activity, handler, callback) {
            public void doWork() throws RemoteException {
                mService.addAcount(mResponse, accountType, authTokenType,
                        requiredFeatures, activity != null, optionsIn);
            }
        }.start();
    }

在doWork()方法的實現中,調用AccountManager持有的AccountManagerService的代理對象(mService)向AccountManagerService發起IPC。

2. AccountManger調用AmsTask匿名子類的start()方法啟動任務。
3. start()方法會調用本類的doWork()方法,在這裡就是執行AccountManagerService的addAccount()操作。
4. 根據FutureTask的實現機制,在任務執行的結束時期,會調用本類的done()方法。AmsTask類覆蓋瞭這個方法:

 

[java]  protected void done() { 
    if (mCallback != null) { 
        postToHandler(mHandler, mCallback, this); 
    } 

        protected void done() {
            if (mCallback != null) {
                postToHandler(mHandler, mCallback, this);
            }
        }
這裡的實現調用瞭AccountManager.postHandler()方法。看名字就可以猜到,這裡將mCallback回調對象裡面的run()方法傳送給主線程的handler進行調用:

 

[java]  private void postToHandler(Handler handler, final AccountManagerCallback<Bundle> callback, 
        final AccountManagerFuture<Bundle> future) { 
    handler = handler == null ? mMainHandler : handler; 
    handler.post(new Runnable() { 
        public void run() { 
            callback.run(future); 
        } 
    }); 

    private void postToHandler(Handler handler, final AccountManagerCallback<Bundle> callback,
            final AccountManagerFuture<Bundle> future) {
        handler = handler == null ? mMainHandler : handler;
        handler.post(new Runnable() {
            public void run() {
                callback.run(future);
            }
        });
    }

在這一次調用中,三個參數的來源分別是:
– handler: mHandler,即當前應用的主線程
– callback: 這個由調用AccountManager的應用程序提供
– future: this,即當前AmsTask實例,它實現瞭AccountManagerCallback接口,包含的是跨進成執行添加帳號操作的返回結果,是一個Bundler對象:
** 包含一個Intent實例:表明帳號創建需要啟動其指定的activity來與用戶交互,用戶將提供驗證信息,如用戶名、密碼
** 或者包含已經創建的帳號的名稱和類型
而應用程序將根據這個Bundle裡面封裝的實際內容采取下一步行動。

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *