Android5.1 联系人号码搜索过程缓存原理

1.至于继承关系就不说了,主要说说怎么搜索的,在这里代码主要在packages/apps/ContactsCommon中 
,联系人界面是PeopleActivity,主要搜索所在的界面是ContactEntryListFragment,在这里面,当你按下搜索按钮的时候,会调用setQueryString方法,继而调用reloadData()方法:

        removePendingDirectorySearchRequests();
        mAdapter.onDataReload();
        mLoadPriorityDirectoriesOnly = true;
        mForceLoad = true;
        startLoading();

mAdapter是在createListAdapter中创建的,看DefaultContactBrowseListFragment中的createListAdapter,在这里定义:

DefaultContactListAdapter adapter = new DefaultContactListAdapter(getContext());

是这个类型的,mAdapter.onDataReload()所作的就是先把缓存中的数据加载好,接下来调用 startLoading;

2. startLoading()中截取一部分:

  if (directoryPartition.isPriorityDirectory() || !mLoadPriorityDirectoriesOnly) {
                        startLoadingDirectoryPartition(i);
                    }
                }
            } else {
    getLoaderManager().initLoader(i, null, this);
            }

这里 startLoadingDirectoryPartition回去加载缓存中的数据,第一次进来的时候执行getLoaderManager().initLoader(i, null, this),这个回去调用当前类中继承的LoadManager的onCreateLoader方法:
if (id == DIRECTORY_LOADER_ID) {
            DirectoryListLoader loader = new DirectoryListLoader(mContext);
            loader.setDirectorySearchMode(mAdapter.getDirectorySearchMode());
            loader.setLocalInvisibleDirectoryEnabled(
                    ContactEntryListAdapter.LOCAL_INVISIBLE_DIRECTORY_ENABLED);
            return loader;
        } else {
            CursorLoader loader = createCursorLoader(mContext);
            long directoryId = args != null && args.containsKey(DIRECTORY_ID_ARG_KEY)
                    ? args.getLong(DIRECTORY_ID_ARG_KEY)
                    : Directory.DEFAULT;
            mAdapter.configureLoader(loader, directoryId);
            return loader;
}

在这里会根据ID去选择调用哪个,如果是缓存什么数据都没有,会实例化一个 CursorLoader,mAdapter.configureLoader(loader, directoryId)回去配置CursorLoader的一些查询字段和拼接查询字符串,可以去看这个类的实现,其实是使用这个类去查询需要搜索的数据;最后回调onLoadFinished方法:

 if (loaderId == DIRECTORY_LOADER_ID) {
            mDirectoryListStatus = STATUS_LOADED;
            mAdapter.changeDirectories(data);
            startLoading();
        } else {
            onPartitionLoaded(loaderId, data);
            if (isSearchMode()) {
                int directorySearchMode = getDirectorySearchMode();
                if (directorySearchMode != DirectoryListLoader.SEARCH_MODE_NONE) {
                    if (mDirectoryListStatus == STATUS_NOT_LOADED) {
                        mDirectoryListStatus = STATUS_LOADING;
                        getLoaderManager().initLoader(DIRECTORY_LOADER_ID, null, this);
                    } else {
                        startLoading();
                    }
                }
            } else {
                mDirectoryListStatus = STATUS_NOT_LOADED;
                getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
            }

在这里也有两个选择,第一次查询一个字段进入的是下面的逻辑,最后调用 getLoaderManager().initLoader再重新去走一遍onCreateLoader,目的是进入onCreateLoader方法的第一个选择,使用 DirectoryListLoader类去查询,其实 DirectoryListLoader就是用来查询缓存中的数据,最后进入onLoadFinished中的第一个选择,mAdapter.changeDirectories(data)所做的就是将data数据进行真正的缓存到DirectoryPartition中,这个类可以自己查看了解,data数据是onCreateLoader中调用 CursorLoader 的时候会去自动查询数据并且返回data到onLoadFinished中,查询动作在 CursorLoader中,最后调用 changeDirectories:
 cursor.moveToPosition(-1);
        while (cursor.moveToNext()) {
            long id = cursor.getLong(idColumnIndex);
            directoryIds.add(id);
            if (getPartitionByDirectoryId(id) == -1) {
                DirectoryPartition partition = new DirectoryPartition(false, true);
                partition.setDirectoryId(id);
                if (isRemoteDirectory(id)) {
                    partition.setLabel(mContext.getString(R.string.directory_search_label));
                } else {
                    partition.setLabel(mDefaultFilterHeaderText.toString());
                }
                partition.setDirectoryType(cursor.getString(directoryTypeColumnIndex));
                partition.setDisplayName(cursor.getString(displayNameColumnIndex));
                int photoSupport = cursor.getInt(photoSupportColumnIndex);
                partition.setPhotoSupported(photoSupport == Directory.PHOTO_SUPPORT_THUMBNAIL_ONLY
                        || photoSupport == Directory.PHOTO_SUPPORT_FULL);
                addPartition(partition);
            }
        }

        // Phase II: remove deleted directories
        int count = getPartitionCount();
        for (int i = count; --i >= 0; ) {
            Partition partition = getPartition(i);
            if (partition instanceof DirectoryPartition) {
                long id = ((DirectoryPartition)partition).getDirectoryId();
                if (!directoryIds.contains(id)) {
                    removePartition(i);
                }
            }
        }

        invalidate();
        notifyDataSetChanged();

在这里拿到数据就更新了。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值