同步适配器模式(三)

同步适配器是一个由android平台处理的service,该service通过账户实现与服务器的身份验证,使用ContentProvider同步数据。实现同步适配器后,应用程序可以自动与服务器一起注册到设备中。同步适配器每次只运行一个,这样就可以避免网络阻塞。

实现同步适配器需要以下几步:

1. 清单文件中声明该同步适配器
<service android:name= ".service.TodoSyncService" >
    <intent-filter >
        <action android:name ="android.content.SyncAdapter" />
    </intent-filter >

    <meta-data
        android:name= "android.content.SyncAdapter"
        android:resource= "@xml/todo_sync_adapter" />
</service>

2. service引入的资源文件
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
    android:contentAuthority="com.manning.androidhacks.hack023.provider.TodoContentProvider"
    android:accountType="com.manning.androidhacks.hack023" />
其中用到了内容提供者的authority和accountType,一定要一致

3. 实现继承自AbstractThreadSyncAdapter的类,源码如下
public class TodoSyncAdapter extends AbstractThreadedSyncAdapter {

     private static final String TAG = TodoSyncAdapter.class.getCanonicalName();
     private final ContentResolver mContentResolver;
     private AccountManager mAccountManager;
     private final static TodoDAO mTodoDAO = TodoDAO.getInstance();

     public TodoSyncAdapter(Context context, boolean autoInitialize) {
            super(context, autoInitialize);
            mContentResolver = context.getContentResolver();
            mAccountManager = AccountManager. get(context);
     }

// 这个方法是在后台线程中执行的,与服务器同步的逻辑就放在该方法中。
     @Override
     public void onPerformSync(Account account, Bundle extras, String authority,
                ContentProviderClient provider, SyncResult syncResult) {

           String authtoken = null;
            try {
                authtoken = mAccountManager.blockingGetAuthToken(account,
                          AuthenticatorActivity. PARAM_AUTHTOKEN_TYPE, true );
                // 第一步,从服务器获取数据
                List<Todo> data = fetchData();
// 第二步,从本地删除服务器端已经删除的条目
                syncRemoteDeleted(data);
// 第三步,把服务器数据同步到本地
                syncFromServerToLocalStorage(data);
// 第四步,把本地同步到服务器
                syncDirtyToServer( mTodoDAO.getDirtyList( mContentResolver));

           } catch (Exception e) {
                handleException(authtoken, e, syncResult);
           }

     }
// 处理异常
     private void handleException(String authtoken, Exception e,
                SyncResult syncResult) {
            if (e instanceof AuthenticatorException) {
                syncResult. stats. numParseExceptions++;
                Log. e(TAG, "AuthenticatorException" , e);
           } else if (e instanceof OperationCanceledException) {
                Log. e(TAG, "OperationCanceledExcepion" , e);
           } else if (e instanceof IOException) {
                Log. e(TAG, "IOException" , e);
                syncResult. stats. numIoExceptions++;
           } else if (e instanceof AuthenticationException) {
                 mAccountManager.invalidateAuthToken(
                          AuthenticatorActivity. PARAM_ACCOUNT_TYPE, authtoken);
                 // The numAuthExceptions require user intervention and are
                 // considered hard errors.
                 // We automatically get a new hash, so let's make SyncManager retry
                 // automatically.
                syncResult. stats. numIoExceptions++;
                Log. e(TAG, "AuthenticationException" , e);
           } else if (e instanceof ParseException) {
                syncResult. stats. numParseExceptions++;
                Log. e(TAG, "ParseException" , e);
           } else if (e instanceof JsonParseException) {
                syncResult. stats. numParseExceptions++;
                Log. e(TAG, "JSONException" , e);
           } else if (e instanceof AndroidHacksException) {
                Log. e(TAG, "AndroidHacksException" , e);
           }
     }

}

4. 最后一步是实现上述的service
public   class   TodoSyncService   extends   Service {
    private   static   final   Object   sSyncAdapterLock   =   new   Object();
    private   static   TodoSyncAdapter   sSyncAdapter   =   null ;

    @Override
    public   void   onCreate() {
      synchronized   (   sSyncAdapterLock ) {
        if   ( sSyncAdapter   ==   null ) {
          sSyncAdapter   =   new   TodoSyncAdapter(getApplicationContext(),
              true );
      }
    }
  }

    @Override
    public   IBinder onBind(Intent intent) {
      return   sSyncAdapter .getSyncAdapterBinder();
  }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值