zoukankan      html  css  js  c++  java
  • Android原生Calendar代码阅读(一)

    原生Calendar代码:

    5.0Calendar源码.rar


    提取的JavaDoc:

    Calendar的javadoc.rar

    1. AsyncQueryService和AsyncQueryServiceHelper。

      Calendar的主入口是AllInOneActivity,这个类实现了一个重要的接口——CalendarController.EventHandler,它的父类是AbstractCalendarActivity。

      先来看AbstractCalendarActivity,它是AllInOneActivity, EditEventActivity, SelectVisibleCalendarsActivity这三个类的父类。其内容很简单:

    public abstract class AbstractCalendarActivity extends Activity {
        protected AsyncQueryService mService;
    
        public synchronized AsyncQueryService getAsyncQueryService() {
            if (mService == null) {
                mService = new AsyncQueryService(this);
            }
            return mService;
        }
    }
    

      包含一个AsyncQueryService变量和对应的get方法,并且get方法还是加锁的,保证了AsyncQueryService对象的唯一性。

      那么这个AsyncQueryService对象是干什么用的?从名字可以看出,这是一个“异步查询服务”,但它并不继承自Service,而是继承自Handler。这个类的注释很详细,总结如下:

    • 这是一个辅助类,是用来在后台Service中执行ContentResolver调用的。它将因为调用方(活动)被杀而导致调用丢失的可能性降至最低。
    • 它被设计用来将AsyncQueryHandler在后台线程调用ContentResolver的方式简单的迁移到Calendar中。
    • 这个类支持增删改查和批量操作,它也支持延迟处理和时限内取消操作。注意一个应用中只有一个队列来序列化所有调用。

      上面说了,本质上AsyncQueryService是个Handler,但它又要在后台Service中执行操作,这个Service就是AsyncQueryServiceHelper,AsyncQueryServiceHelper是IntentService的子类。

      所以,AsyncQueryService的基本操作模式是,外部调用其添删改查方法时,它把方法参数和自身的引用交给一个IntentService,由这个IntentService来实际执行添删改查操作。执行完后,IntentSerice会给Handler回送消息。而在AsyncQueryService的handlerMessage中,它会根据操作类别回调不同的方法,例如onDeleteComplete。

      因此,在使用AsyncQueryService时,我们需要实现自己的子类,重写onDeleteComplete等方法,就可以实现自动在后台服务中做数据操作,操作结束后在主线程回调操作结果。

      注意一点,上面的AbstractCalendarActivity中的AsyncQueryService对象是直接实例化的,没有重写任何回调方法。因为这个对象只在EditEventHelper中用到了:

    public EditEventHelper(Context context) {
        mService = ((AbstractCalendarActivity)context).getAsyncQueryService();
    }
    

    mService.startBatch(mService.getNextToken(), null, android.provider.CalendarContract.AUTHORITY, ops,
                Utils.UNDO_DELAY);
    

    只需要编辑后台数据,无需回调显示到视图上。

      AsyncQueryService的结构并不复杂,但其中有一些细节值得学习:

    1. 使用AtomicInteger类和它的getAndIncrement方法,获得数据操作的token。关于原子操作的介绍见Java 理论与实践: 流行的原子

    2. AsyncQueryService传递给AsyncQueryServiceHelper的Handler引用没有直接用this,而是用的mHander,便于测试。

      private Handler mHandler = this; // can be overridden for testing

      // @VisibleForTesting
      protected void setTestHandler(Handler handler) {
      mHandler = handler;
      }

    3. AsyncQueryServiceHelper实例化了一个静态常量的队列来存储数据操作信息,因此这个队列对于应用是唯一的。注意这里使用了PriorityQueue,它会按操作的计划时间来自动对其排序,这是因为OperationInfo类实现了Comparable接口。

    4. 后台查询得到Cursor对象后,主动调用了一次cursor.getCount()方法,这样可以让主线程中对Cursor中数据的访问加快:

                   try {
                       cursor = resolver.query(args.uri, args.projection, args.selection,
                               args.selectionArgs, args.orderBy);
                       /*
                        * Calling getCount() causes the cursor window to be
                        * filled, which will make the first access on the main
                        * thread a lot faster
                        */
                       if (cursor != null) {
                           cursor.getCount();
                       }
                   } catch (Exception e) {
                       Log.w(TAG, e.toString());
                       cursor = null;
                   }
  • 相关阅读:
    VS2015使用scanf报错解决方案
    C++的标准模板库(STL)简介
    C++中常用特殊符号简介(& , * , : , :: , ->)
    C++中#include <xxx.h>和#include "xxx.h"的区别(尖括号和双引号的区别)
    C++中#include的工作原理
    opencv中Mat与IplImage,CVMat类型之间转换
    C++数据类型简析
    让你在DOS中任意切换目录
    七种Prolog解释器/编译器
    C++中引用(&)的用法和应用实例
  • 原文地址:https://www.cnblogs.com/yuanchongjie/p/4834234.html
Copyright © 2011-2022 走看看