- 對於帳號管理,由介面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裡面封裝的實際內容採取下一步行動。