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();
在这里拿到数据就更新了。