android数据库更新简介

来源:互联网 发布:编程代码有几种 编辑:程序博客网 时间:2024/06/09 14:37

  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函数来通知它们监控的数据发生变化了。

1 0
原创粉丝点击