我学习时所用的Android 版本是2.33, API 10.
在Android的安装目录下的Sample目录下可以找到这个例子。
一、 初看代码
在上半部分列出了仅有的两个联系人!我很想知道实现这个代码是如何写的,这个Activity的onCreate事件代码如下:
public void onCreate(Bundle savedInstanceState) { Log.v(TAG, "Activity State: onCreate()"); super.onCreate(savedInstanceState); setContentView(R.layout.contact_manager); // Obtain handles to UI objects mAddAccountButton = (Button) findViewById(R.id.addContactButton); mContactList = (ListView) findViewById(R.id.contactList); mShowInvisibleControl = (CheckBox) findViewById(R.id.showInvisible); // Initialize class properties mShowInvisible = false; mShowInvisibleControl.setChecked(mShowInvisible); // Register handler for UI elements mAddAccountButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Log.d(TAG, "mAddAccountButton clicked"); launchContactAdder(); } }); mShowInvisibleControl.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Log.d(TAG, "mShowInvisibleControl changed: " + isChecked); mShowInvisible = isChecked; populateContactList(); } }); // Populate the contact list populateContactList(); }
我们可以在这段代码的尾部看到这样一句:populateContactList(), 而这个函数的代码如下:
private void populateContactList() { // Build adapter with contact entries Cursor cursor = getContacts(); String[] fields = new String[] { ContactsContract.Data.DISPLAY_NAME }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.contact_entry, cursor, fields, new int[] {R.id.contactEntryText}); mContactList.setAdapter(adapter); } /** * Obtains the contact list for the currently selected account. * * @return A cursor for for accessing the contact list. */ private Cursor getContacts() { // Run query Uri uri = ContactsContract.Contacts.CONTENT_URI; String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME }; String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + (mShowInvisible ? "0" : "1") + "'"; String[] selectionArgs = null; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; return managedQuery(uri, projection, selection, selectionArgs, sortOrder); }
由代码我们知道populateContactList()函数是通过getContacts函数获得的数据集,然后通过SimpleCursorAdapter 将数据显示到ListView当中的!查看getContacts()函数的代码我们知道,getContacts()函数的数据集是通过这句代码返回的:return managedQuery(uri, projection, selection, selectionArgs, sortOrder); 对此,我很疑惑,
managedQuery()的作用是什么呢?查看帮助如下:
public final Cursor managedQuery (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
Since: API Level 1
This method is deprecated.
Use CursorLoader
instead.
Wrapper around query(android.net.Uri, String[], String, String[], String)
that gives the resulting Cursor
to call startManagingCursor(Cursor)
so that the activity will manage its lifecycle for you. If you are targeting HONEYCOMB
or later, consider instead using LoaderManager
instead, available via getLoaderManager()
.
Parameters
uri The URI of the content provider to query.
projection List of columns to return.
selection SQL WHERE clause.
selectionArgs The arguments to selection, if any ?s are pesent
sortOrder SQL ORDER BY clause.
Returns
- The Cursor that was returned by query().
此函数是对query的封装,返回一个Cursor,其各个参数的含意是:
uri 你要查询的内容提供者(content provider)的URI(不知道可不可以翻译为地址)
projection 要返回的columns列表
selection SQL语句的where子句
selectionArgs selection的参数,如果包含?,?号将会被参数所替换
sortOrder SQL的ORDER BY排序子句
所以,我们知道,managedQuery 就是针对一个目录的sql select 语句!所以,我们再来看看该例子的managedQuery 是怎么写的
Uri uri = ContactsContract.Contacts.CONTENT_URI; String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME }; String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + (mShowInvisible ? "0" : "1") + "'"; String[] selectionArgs = null; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; return managedQuery(uri, projection, selection, selectionArgs, sortOrder);
从代码中我们知道,他用到了好多在ContactsContract中定义的常量
ContactsContract.Contacts.CONTENT_URI : contacts的查询uri
ContactsContract.Contacts._ID :contacts表的_ID列,意思The unique ID for a row.
ContactsContract.Contacts.DISPLAY_NAME:
public static final String DISPLAY_NAME
Since: API Level 5
The display name for the contact. //联系人的显示名称
Type: TEXT
Constant Value: "display_name"
COLLATE LOCALIZED ASC : 根据本地的语言特征对字符串进行升序排序,意思是说对联系人名称进行升序排序
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + (mShowInvisible ? "0" : "1") + "'";
这个Where子句根据mShowInvisible的值出现不同的表现,学过C语系的程序员都懂的
也就是说,这句managedQuery(uri, projection, selection, selectionArgs, sortOrder);的目的是根据mShowInvisible的值返回对contacts的一个升序查询。
获得数据集后,再通过SimpleCursorAdapter 将DISPLAY_NAME显示出来!