android数据库更新简介



  1. 概述

    Android应用程序组件Content Provider中的数据更新通知机制和Android系统中的广播通知机制的有点类似。它们有三个主要区别,区别一是前者是通过URI来把通知的发送者和接收者关联在一起的,而后者是通过intent来关联的;二是前者的通知注册中心是由ContentService服务来扮演,而后者是由ActivityManagerService服务来扮演的;三是前者负责接收数据更新通知的类必须要继承ContentObserver类,而后者要继承BroadcastReceiver类。下面分三个部分来分析数据更新流程。1ContentService的启动过程;2、监控数据变化的ContentObserver的注册过程;3、数据更新通知的发送过程。

  2. ContentService的启动过程

    Android系统进程Zygote在启动的时候,会加载系统的一些关键服务,ContentService就这些关键服务之一。如图所示:

        private static final String CONTENT_SERVICE_CLASS =
    "com.android.server.content.ContentService$Lifecycle";
    mSystemServiceManager.startService(CONTENT_SERVICE_CLASS);
    public final class ContentService extends IContentService.Stub {    static final String TAG = "ContentService";    static final boolean DEBUG = false;    public static class Lifecycle extends SystemService {        private ContentService mService;        public Lifecycle(Context context) {            super(context);        }        @Override        public void onStart() {            final boolean factoryTest = (FactoryTest                    .getMode() == FactoryTest.FACTORY_TEST_LOW_LEVEL);            mService = new ContentService(getContext(), factoryTest);            publishBinderService(ContentResolver.CONTENT_SERVICE_NAME, mService);        }

        protected final void publishBinderService(String name, IBinder service) {
    publishBinderService(name, service, false);
    }

    /**
    * Publish the service so it is accessible to other services and apps.
    */
    protected final void publishBinderService(String name, IBinder service,
    boolean allowIsolated) {
    ServiceManager.addService(name, service, allowIsolated);
    }

    可以看出,在ContentService的内部类Lifecycle类的onStart函数中,会创建ContentService实例,然后把它添加到ServiceManager中去,这样ContentService服务就启动起来了,其他地方就可以通过ServiceManager来获得它的一个远程接口来使用它提供的服务。

  3. ContentOberver的注册过程

    在应用层注册观察者需要继承ContentObserver并实现onChange函数。当这个ContentObserver子类负责监控的数据发生变化时,ContentService就会调用它的onChange函数来处理。注册过程如下:

        public void registerContentObserver(Uri uri, boolean notifyForDescendants,
    IContentObserver observer, int userHandle) {
    synchronized (mRootNode) {
    mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
    uid, pid, userHandle);
    if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
    " with notifyForDescendants " + notifyForDescendants);
    }

    最后调用了ContentService类的成员变量mRootNodeaddObserverLocked函数来注册这个ContentObserver对象observer,成员变量mRootNode的类型为ContentService在内部定义的一个类ObserverNode。注册到ContentService中的ContentObserver按照树形来组织,树的节点类型为ObserverNode,而树的根节点就为ContentService类的成员变量mRootNode,每一个ObserverNode节点都对应一个名字,它是从URI中解析出来的。

  4. 数据更新通知的发送过程

    在联系人数据库的增删改查操作都会发出通知,如下:

        public Uri insert(Uri uri, ContentValues values) {
    ContactsTransaction transaction = startTransaction(false);
    try {
    Uri result = insertInTransaction(uri, values);
    if (result != null) {
    transaction.markDirty();
    }
    transaction.markSuccessful(false);
    return result;
    } finally {
    endTransaction(false);
    }
    }
        private void endTransaction(boolean callerIsBatch) {        ContactsTransaction transaction = mTransactionHolder.get();        if (transaction != null && (!transaction.isBatch() || callerIsBatch)) {            try {                if (transaction.isDirty()) {                    notifyChange();                }            }         }    }

        protected void notifyChange() {
    notifyChange(mSyncToNetwork);
    mSyncToNetwork = false;
    }

    protected void notifyChange(boolean syncToNetwork) {
    getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null,
    syncToNetwork);
    }

    从上面可看出在content provider中会调用notifyChange来通知那些注册了监控content://com.android.contacts这个URIContentObserver,它监控的数据发生变化了。

    最后还是调用到了ContentService中:

        public void notifyChange(Uri uri, IContentObserver observer,
    boolean observerWantsSelfNotifications, int flags,
    int userHandle) {
    try {
    ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>();
    synchronized (mRootNode) {
    mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications,
    flags, userHandle, calls);
    }
    final int numCalls = calls.size();
    for (int i=0; i<numCalls; i++) {
    ObserverCall oc = calls.get(i);
    try {
    oc.mObserver.onChange(oc.mSelfChange, uri, userHandle);
    if (DEBUG) Slog.d(TAG, "Notified " + oc.mObserver + " of " + "update at "
    + uri);
    }
    }
    }

    这里会先调用collectObserverLocked函数来手机那些注册了上面URIContentObserver,然后分别调用这些ContentObserveronChange函数来通知它们监控的数据发生变化了。

智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告