queryHandler.startQuery(token, cookie, uri, projection, selection, selectionArgs, sortBy);
1. 当你实例化一个AsyncQueryHandler类时(包括其子类...),它会单件构造一个线程(后面会详述...),这个线程里面会构建一个消息循环。
2. 获得该消息循环的指针,用它做参数实例化另一个Handler类,该类为内部类。至此,就有了两个线程,各自有一个Handler来处理消息。
3. 当调用onXXX的时候,在XXX函数内部会将请求封装成一个内部的参数类,将其作为消息的参数,将此消息发送至另一个线程。
4. 在该线程的Handler中,接受该消息,并分析传入的参数,用初始化时传入的ContentResolver进行XXX操作,并返回Cursor或其他返回值。
5. 构造一个消息,将上述返回值以及其他相关内容绑定在该消息上,发送回主线程。
6. 主线程默认的AsyncQueryHandler类的handleMessage方法(可自定义,但由于都是内部类,基本没有意义...)会分析该消息,并转发给对应的onXXXComplete方法。
7. 用户重写的onXXXComplete方法开始工作。
好了 直接上代码:
package org.dxt.list; import static android.view.Window.PROGRESS_VISIBILITY_OFF; import static android.view.Window.PROGRESS_VISIBILITY_ON; import android.app.ListActivity; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.widget.CursorAdapter; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import android.widget.TextView; import android.widget.Toast; public class AsyncQueryActivity extends ListActivity { private ListView myListView; private EditText myEditText_Name; private EditText myEditText_Tel; private String name = null; private String tel = null; private MyQueryHandler mAsyncQueryActivity; private CursorAdapter mCursorAdapter; private Cursor mCursor = null; private TextView mEmptyText; protected final static int MENU_ADD = Menu.FIRST; protected final static int MENU_UPDATE = Menu.FIRST + 1; protected final static int MENU_DELETE = Menu.FIRST + 2; protected final static int MENU_SEARCH = Menu.FIRST + 3; protected final static int MENU_SEARCH_ALL = Menu.FIRST + 4; protected final static int MENU_DELETE_ALL = Menu.FIRST + 5; protected static final String ADD = "add"; protected static final String UPDATE = "update"; protected static final String DELETE = "delete"; protected static final String SEARCH = "search"; protected static final String SEARCH_ALL = "search_all"; protected static final String DELETE_ALL = "delete_all"; private static final String[] COLUMN_NAMES = new String[] { MyUsers.User.USER_NAME, MyUsers.User.USER_TEL }; protected static final int QUERY_TOKEN = 0; protected static final int INSERT_TOKEN = 1; protected static final int UPDATE_TOKEN = 2; protected static final int DELETE_TOKEN = 3; protected static final int DELETE_TOKEN_ALL = 4; protected static final int SEARCH_TOKEN = 5; protected int mInitialSelection = -1; @Override public boolean onCreateOptionsMenu(Menu menu) { // TODO Auto-generated method stub super.onCreateOptionsMenu(menu); menu.add(Menu.NONE, MENU_ADD, 0, R.string.ADD); menu.add(Menu.NONE, MENU_UPDATE, 0, R.string.EDIT); menu.add(Menu.NONE, MENU_DELETE, 0, R.string.DELETE); menu.add(Menu.NONE, MENU_SEARCH, 0, R.string.SEARCH); menu.add(Menu.NONE, MENU_SEARCH_ALL, 0, R.string.SEARCH_ALL); menu.add(Menu.NONE, MENU_DELETE_ALL, 0, R.string.DELETE_ALL); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub super.onOptionsItemSelected(item); switch (item.getItemId()) { case MENU_ADD: operation(ADD); break; case MENU_UPDATE: operation(UPDATE); break; case MENU_DELETE: operation(DELETE); break; case MENU_SEARCH: operation(SEARCH); break; case MENU_SEARCH_ALL: operation(SEARCH_ALL); break; case MENU_DELETE_ALL: operation(DELETE_ALL); break; default: break; } return true; } private void initWidget() { // int ScreenWidth = getWindowManager().getDefaultDisplay().getWidth(); // int ScreenHight = getWindowManager().getDefaultDisplay().getHeight(); // Log.d("tag", "ScreenWidth = " + ScreenWidth + "ScreenHight = " // + ScreenHight); myEditText_Name = (EditText) findViewById(R.id.EditText_Name); myEditText_Tel = (EditText) findViewById(R.id.EditText_Tel); myListView = (ListView) findViewById(android.R.id.list); } private void getUserInput() { name = myEditText_Name.getText().toString().trim();// 除去两头的空格 tel = myEditText_Tel.getText().toString().trim(); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.asnyclist); initWidget(); mEmptyText = (TextView) findViewById(android.R.id.empty); mAsyncQueryActivity = new MyQueryHandler(getContentResolver()); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { // TODO Auto-generated method stub super.onListItemClick(l, v, position, id); Log.d("tag", "position------>" + position);// 在这个view上的位置 } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); query(); } @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); if (mCursor != null) { mCursor.deactivate(); } } private void query() { mAsyncQueryActivity.startQuery(QUERY_TOKEN, null,MyUsers.User.CONTENT_URI,null, null, null, "_id desc"); displayProgress(true); } private void reQuery() { query(); } private void displayProgress(boolean flag) { mEmptyText.setText(flag ? R.string.simContacts_emptyLoading : R.string.simContacts_empty); getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, flag ? PROGRESS_VISIBILITY_ON : PROGRESS_VISIBILITY_OFF); } private void setAdapter() { if (mCursorAdapter == null) { mCursorAdapter = newAdapter(); myListView.setAdapter(mCursorAdapter); // setListAdapter(mCursorAdapter); } else { mCursorAdapter.changeCursor(mCursor); myListView.invalidateViews();// 更新listview } if (mInitialSelection >= 0 && mInitialSelection < mCursorAdapter.getCount()) { setSelection(mInitialSelection); getListView().setFocusableInTouchMode(true); boolean gotfocus = getListView().requestFocus(); } } protected CursorAdapter newAdapter() { return new SimpleCursorAdapter(this, R.layout.testlist, mCursor, COLUMN_NAMES, new int[] { R.id.name_text, R.id.tel_text }); } private void operation(String cmd) { getUserInput(); if (cmd.equals(ADD)) { insert(); } else if (cmd.equals(UPDATE)) { update(); } else if (cmd.equals(DELETE)) { delete(); } else if (cmd.equals(SEARCH)) { search(); } else if (cmd.equals(SEARCH_ALL)) { query(); } else if (cmd.equals(DELETE_ALL)) { deleteAll(); // reQuery(); } myEditText_Name.setText(""); myEditText_Tel.setText(""); } private void insert() { if (name.equals("") || tel.equals("")) { Toast.makeText(this, "请输入您要插入数据的用户名!", Toast.LENGTH_SHORT).show(); } else { ContentValues values = new ContentValues(); values.put(MyUsers.User.USER_NAME, name); values.put(MyUsers.User.USER_TEL, tel); mAsyncQueryActivity.startInsert(INSERT_TOKEN, null,MyUsers.User.CONTENT_URI,values); } } private void delete() { if (name.equals("")) { Toast.makeText(this, "请输入您要删除数据的用户名!", Toast.LENGTH_SHORT).show(); } else { mAsyncQueryActivity.startDelete(DELETE_TOKEN, null, MyUsers.User.CONTENT_URI, MyUsers.User.USER_NAME+"=?", new String[]{name}); Toast.makeText(this, "删除" + name + " 成功!", Toast.LENGTH_SHORT).show(); } } private void update() { if (name.equals("")) { Toast.makeText(this, "请输入您要更新数据的用户名!", Toast.LENGTH_SHORT).show(); } else if (tel.equals("")) { Toast.makeText(this, "请输入您要更新数值", Toast.LENGTH_SHORT).show(); } else { ContentValues values = new ContentValues(); // values.put(MyUsers.User.USER_NAME, name); values.put(MyUsers.User.USER_TEL, tel); mAsyncQueryActivity.startUpdate(UPDATE_TOKEN, null, MyUsers.User.CONTENT_URI, values, MyUsers.User.USER_NAME + "=?", new String[]{name}); Toast.makeText(this, "更新为" + tel + " 成功!", Toast.LENGTH_SHORT).show(); } } private void search() { if (name.equals("")) { Toast.makeText(this, "请输入您要查找数据的用户名!", Toast.LENGTH_SHORT).show(); } else { mAsyncQueryActivity.startQuery(SEARCH_TOKEN, null, MyUsers.User.CONTENT_URI, null, MyUsers.User.USER_NAME+"=?", new String[]{name}, null); } } private void deleteAll() { mAsyncQueryActivity.startDelete(DELETE_TOKEN_ALL, null, MyUsers.User.CONTENT_URI, null, null); Toast.makeText(this, "清空成功喽!", Toast.LENGTH_SHORT).show(); } private class MyQueryHandler extends AsyncQueryHandler { public MyQueryHandler(ContentResolver cr) { super(cr); // TODO Auto-generated constructor stub } @Override protected void onDeleteComplete(int token, Object cookie, int result) { // TODO Auto-generated method stub super.onDeleteComplete(token, cookie, result); Log.d("tag", "onDeleteComplete--->"+result); reQuery(); } @Override protected void onInsertComplete(int token, Object cookie, Uri uri) { // TODO Auto-generated method stub super.onInsertComplete(token, cookie, uri); Log.d("tag", "onInsertComplete--->"); reQuery(); } @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { // TODO Auto-generated method stub super.onQueryComplete(token, cookie, cursor); Log.d("tag", "onQueryComplete--->"); mCursor = cursor; setAdapter(); if(cursor.getCount()>0){ displayProgress(false); }else{ displayProgress(true); } } @Override protected void onUpdateComplete(int token, Object cookie, int result) { // TODO Auto-generated method stub super.onUpdateComplete(token, cookie, result); Log.d("tag", "onUpdateComplete--->"); reQuery(); } } }