2021-01-28(性能优化-SyncAdapter框架)

参考

> Android提供的一个同步框架,它将所有的数据传输放到同一个地方,系统智能的安排数据传输,优化电池性能。
  1. 为什么使用SyncAdapter?

    SyncAdapter可以智能安排数据传输,如检查网络连接、下载失败后重试等。可以根据不同条件自动发起数据传输,如服务器数据变更、定时同步等。
    使用SyncAdapter可以加快应用的加载时间、实现离线功能,可以在数据及时同步和减少网络调用以节约电池电量之间达到一种平衡局面。

  2. 何时使用SyncAdapter?

    SyncAdapter适用于需要同步本地数据和在线账户信息的应用,如电子邮件的定时收取、笔记应用的云备份、天气应用的及时同步等。
    SyncAdapter设计为必须与用户账户绑定,即使你的应用不需要账户认证,也需要实现相关的类来处理账户,并可以将其隐藏。

  1. 创建SyncAdapter:

    • 继承AbstractThreadedSyncAdapter基类,在构造方法中做一些初始化设置,如获取ContentResolver实例等。
    • 在onPerformSync()方法中添加数据传输的代码,框架将自动将其放在后台线程中运行。除同步相关任务外,也应将网络相关的任务放在此处,将网络操作集中处理可以降低频繁发起网络的功耗。
    • 可添加辅助方法syncImmediately(),调用此方法来立即执行同步,可用于“刷新”操作:
  2. 创建SyncService服务

    该服务用于将SyncAdapter开放给framework调用,即将SyncAdapter的binder对象传给framework。通过这个binder,framework即可调用onPerformSync()方法。
    在onCreate()中以单实例形式实例化SyncAdapter,这样会将SyncAdapter的实例化延迟到framework首次传输数据创建Service的时候执行。实例化过程须保证线程安全,避免将多次同步响应添加到队列。

     public class SyncService extends Service {
     // Storage for an instance of the sync adapter
     private static SyncAdapter sSyncAdapter = null;
     // Object to use as a thread-safe lock
     private static final Object sSyncAdapterLock = new Object();
     /*
      * Instantiate the sync adapter object.
      */
     @Override
     public void onCreate() {
         /*
          * Create the sync adapter as a singleton.
          * Set the sync adapter as syncable
          * Disallow parallel syncs
          */
         synchronized (sSyncAdapterLock) {
             if (sSyncAdapter == null) {
                 sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
             }
         }
     }
     /**
      * Return an object that allows the system to invoke
      * the sync adapter.
      *
      */
     @Override
     public IBinder onBind(Intent intent) {
         /*
          * Get the object that allows external processes
          * to call onPerformSync(). The object is created
          * in the base class code when the SyncAdapter
          * constructors call super()
          */
         return sSyncAdapter.getSyncAdapterBinder();
     }
     }
    
  3. 创建Authenticator类

    该类继承了AbstractAccountAuthenticator类,用于管理账户认证。如果你的应用不需要账户认证,可以提供一个仅包含方法实现的类,Authenticator的信息将被忽略。

     /*
      * Implement AbstractAccountAuthenticator and stub out all
      * of its methods
      */
     public class Authenticator extends AbstractAccountAuthenticator {
         // Simple constructor
         public Authenticator(Context context) {
             super(context);
         }
         // Editing properties is not supported
         @Override
         public Bundle editProperties(
                 AccountAuthenticatorResponse r, String s) {
             throw new UnsupportedOperationException();
         }
         // Don't add additional accounts
         @Override
         public Bundle addAccount(
                 AccountAuthenticatorResponse r,
                 String s,
                 String s2,
                 String[] strings,
                 Bundle bundle) throws NetworkErrorException {
             return null;
         }
         // Ignore attempts to confirm credentials
         @Override
         public Bundle confirmCredentials(
                 AccountAuthenticatorResponse r,
                 Account account,
                 Bundle bundle) throws NetworkErrorException {
             return null;
         }
         // Getting an authentication token is not supported
         @Override
         public Bundle getAuthToken(
                 AccountAuthenticatorResponse r,
                 Account account,
                 String s,
                 Bundle bundle) throws NetworkErrorException {
             throw new UnsupportedOperationException();
         }
         // Getting a label for the auth token is not supported
         @Override
         public String getAuthTokenLabel(String s) {
             throw new UnsupportedOperationException();
         }
         // Updating user credentials is not supported
         @Override
         public Bundle updateCredentials(
                 AccountAuthenticatorResponse r,
                 Account account,
                 String s, Bundle bundle) throws NetworkErrorException {
             throw new UnsupportedOperationException();
         }
         // Checking features for the account is not supported
         @Override
         public Bundle hasFeatures(
             AccountAuthenticatorResponse r,
             Account account, String[] strings) throws NetworkErrorException {
             throw new UnsupportedOperationException();
         }
     }
    
  4. 创建AuthenticatorService服务

    此服务提供给SyncAdapter framework,用于调用Authenticator的方法。
    在onCreat()中创建Authenticator对象,在onBind()中返回一个binder对象用于在Authenticator和framework间传输数据。

     /**
      * A bound Service that instantiates the authenticator
      * when started.
      */
     public class AuthenticatorService extends Service {
         ...
         // Instance field that stores the authenticator object
         private Authenticator mAuthenticator;
         @Override
         public void onCreate() {
             // Create a new authenticator object
             mAuthenticator = new Authenticator(this);
         }
         /*
          * When the system binds to this Service to make the RPC call
          * return the authenticator's IBinder.
          */
         @Override
         public IBinder onBind(Intent intent) {
             return mAuthenticator.getIBinder();
         }
     }
    
  5. 添加Authenticator的元数据文件

    元数据写在一个xml文件中,用于声明账户类型和一些显示给用户的信息,保存在/res/xml/目录。
    文件名自定义,一般定义为authenticator.xml,根标签为<account-authenticator>,一般有以下属性:

    • android:accountType
      framework把账户类型作为识别SyncAdapter的内部标识,对于需要验证账户的应用,账户类型会和账户名一起发送给服务器进行验证;对于不需要验证的应用,也要提供账户类型,用于标明一个控制域,framework用这个账户类型类管理你的SyncAdapter,但是不会发送给服务器。

    • android:icon
      指向用做图标的Drawable资源。如果在res/xml/syncadapter.xml 设置了android:userVisible="true” 属性将Sync adapter对用户可见,则必须要提供一个图标资源。它将显示在“设置”应用的“账号”一项中。

    • android:smallIcon
      小图标,根据屏幕尺寸可能在设置中代替icon属性。
      a- ndroid:label
      标识账户类型,一般为应用名。

      <?xml version="1.0" encoding="utf-8"?>
      <account-authenticator
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:accountType="example.com"
      android:icon="@drawable/ic_launcher"
      android:smallIcon="@drawable/ic_launcher"
      android:label="@string/app_name"/>

  6. 在清单文件中声明AuthenticatorService

     <service
     android:name="com.example.android.syncadapter.AuthenticatorService">
     <intent-filter>
         <action android:name="android.accounts.AccountAuthenticator"/>
     </intent-filter>
     <meta-data
         android:name="android.accounts.AccountAuthenticator"
         android:resource="@xml/authenticator" />
     </service>
    

    <intent-filter>设置了通过actionandroid.accounts.AccountAuthenticator启动的filter。这个action是由系统发送的。当被触发时,系统会启动封装了你的Authtenticator的AuthenticatorService。
    <meta-data>声明了authenticator的元数据。通过android:name 属性将meta-data与认证框架关联。android:resource指定元数据文件。

其他步骤参考原链接

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容