Contacts联系人查询过程

Contacts联系人查询过程:

(这是android2.2,2,2.3上联系人查询过程)

 

protected void onCreate(Bundle icicle) {

       if (UI.LIST_DEFAULT.equals(action)) {

            mMode = MODE_DEFAULT; //设置模式

            setEmptyText();     //还未导入数据库的联系人之前,界面显示为空。

        mAdapter = new ContactItemListAdapter(this);

        setListAdapter(mAdapter);

        getListView().setOnScrollListener(mAdapter);    //设置ITEMLIST


        // We manually save/restore the listview state

        list.setSaveEnabled(false);

        mQueryHandler = new QueryHandler(this);   //获取查询实例

        mJustCreated = true;  //第一次打开标志

        // TODO(jham) redesign this

        mSyncEnabled = true;

}

// 重新执行

protected void onResume() {

              boolean runQuery = true;  //查询标志

        if (mMode == MODE_DEFAULT) {

            // If we're in default mode we need to possibly reset the mode due to a change

            // in the preferences activity while we weren't running

            setDefaultMode();   //设置模式

        }

        if (mJustCreated && runQuery) {

            // We need to start a query here the first time the activity is launched, as long

            // as we aren't doing a filter.

            startQuery();   //开始查询

        }

        mJustCreated = false; 

    }


// 设置模式函数

private void setDefaultMode() {

        // Load the preferences

              log("setDefaultMode() <wlq>");

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);

 

        mDisplayOnlyPhones = prefs.getBoolean(Prefs.DISPLAY_ONLY_PHONES,

                Prefs.DISPLAY_ONLY_PHONES_DEFAULT);

 

        // Update the empty text view with the proper string, as the group may have changed

        setEmptyText();

    }


// 查询方法

void startQuery() {

              log("startQuery() <wlq>");

        mAdapter.setLoading(true);

              String[] projection = getProjectionForQuery();//获取查询要查询的项目:数据库字段、表名

        String callingPackage = getCallingPackage();

        Uri uri = getUriToQuery();  //获取数据库链接uri=content://com.android.contacts/contacts

        if (!TextUtils.isEmpty(callingPackage)) {

            uri = uri.buildUpon()

                    .appendQueryParameter(ContactsContract.REQUESTING_PACKAGE_PARAM_KEY,

                            callingPackage)

                    .build();

        }

 

            case MODE_DEFAULT:

            case MODE_PICK_CONTACT:

            case MODE_PICK_OR_CREATE_CONTACT:

            case MODE_INSERT_OR_EDIT_CONTACT:

                mQueryHandler.startQuery(QUERY_TOKEN, null, uri,

                        projection, getContactSelection(), null,

getSortOrder(projection)); //开始查询参数:查询标识、未知、数据库链接、数据库字段和表、查

//询策略(WHERE)、策略数(AND)、排序关键字

                break;

 

}


frameworks\base\core\java\android\contect\ AsyncQueryHandler.java

// 发送查询消息

public void startQuery(int token, Object cookie, Uri uri,

            String[] projection, String selection, String[] selectionArgs,

String orderBy) {

//参数:查询标识、未知、数据库链接、数据库字段和表、查询策略(WHERE)、策略数(AND)、//排序关键字

        // Use the token as what so cancelOperations works properly

        Message msg = mWorkerThreadHandler.obtainMessage(token);

        msg.arg1 = EVENT_ARG_QUERY;

 

        WorkerArgs args = new WorkerArgs();

        args.handler = this;

        args.uri = uri;

        args.projection = projection;

        args.selection = selection;

        args.selectionArgs = selectionArgs;

        args.orderBy = orderBy;

        args.cookie = cookie;

        msg.obj = args;

 

        mWorkerThreadHandler.sendMessage(msg);//通过消息轮询机制来实现查询

    }

 

Packages\Provider\ContactsProvider\contactsProvider.java


public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,

            String sortOrder) {

       final SQLiteDatabase db = mDbHelper.getReadableDatabase();

       SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

String limit = getLimit(uri);

 

 

return query(db, qb, projection, selection, selectionArgs, sortOrder, groupBy, limit);

} 


private Cursor query(final SQLiteDatabase db, SQLiteQueryBuilder qb, String[] projection,

            String selection, String[] selectionArgs, String sortOrder, String groupBy,

            String limit) {

              final SQLiteDatabase db = mDbHelper.getReadableDatabase();

 

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        String groupBy = null;

        String limit = getLimit(uri);

               Log.v(TAG, "query: limit=" + limit);

        // TODO: Consider writing a test case for RestrictionExceptions when you

        // write a new query() block to make sure it protects restricted data.

        final int match = sUriMatcher.match(uri);

              Log.v(TAG, "query: match=" + match);

 

              case CONTACTS: {

                setTablesAndProjectionMapForContacts(qb, uri, projection);

                break;

            }

              return query(db, qb, projection, selection, selectionArgs, sortOrder, groupBy, limit);

}


private void setTablesAndProjectionMapForContacts(SQLiteQueryBuilder qb, Uri uri,

            String[] projection) {

        StringBuilder sb = new StringBuilder();

        boolean excludeRestrictedData = false;

        String requestingPackage = uri.getQueryParameter(

                ContactsContract.REQUESTING_PACKAGE_PARAM_KEY);

        if (requestingPackage != null) {

            excludeRestrictedData = !mDbHelper.hasAccessToRestrictedData(requestingPackage);

        }

        sb.append(mDbHelper.getContactView(excludeRestrictedData));

        if (mDbHelper.isInProjection(projection,

                Contacts.CONTACT_PRESENCE)) {

            sb.append(" LEFT OUTER JOIN " + Tables.AGGREGATED_PRESENCE +

                    " ON (" + Contacts._ID + " = " + AggregatedPresenceColumns.CONTACT_ID + ")");

        }

        if (mDbHelper.isInProjection(projection,

                Contacts.CONTACT_STATUS,

                Contacts.CONTACT_STATUS_RES_PACKAGE,

                Contacts.CONTACT_STATUS_ICON,

                Contacts.CONTACT_STATUS_LABEL,

                Contacts.CONTACT_STATUS_TIMESTAMP)) {

            sb.append(" LEFT OUTER JOIN " + Tables.STATUS_UPDATES + " "

                    + ContactsStatusUpdatesColumns.ALIAS +

                    " ON (" + ContactsColumns.LAST_STATUS_UPDATE_ID + "="

                            + ContactsStatusUpdatesColumns.CONCRETE_DATA_ID + ")");

        }

        qb.setTables(sb.toString());

        qb.setProjectionMap(sContactsProjectionMap);

}

 

 

 


private Cursor query(final SQLiteDatabase db, SQLiteQueryBuilder qb, String[] projection,

            String selection, String[] selectionArgs, String sortOrder, String groupBy,

            String limit) {

                    Log.v(TAG, "query: selection=" + selection);

        if (projection != null && projection.length == 1

                && BaseColumns._COUNT.equals(projection[0])) {

            qb.setProjectionMap(sCountProjectionMap);

        }

        final Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, null,

                sortOrder, limit);

        if (c != null) {

            c.setNotificationUri(getContext().getContentResolver(), ContactsContract.AUTHORITY_URI);

        }

        return c;

    }

 

frameworks\base\core\java\android\database\sqlite\SQLiteQueryBuilder.java

public Cursor query(SQLiteDatabase db, String[] projectionIn,

            String selection, String[] selectionArgs, String groupBy,

            String having, String sortOrder) {

                     log(" query() sortOrder="+sortOrder+"<-wlq->");

        return query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder,

                null /* limit */);

    }

 

public Cursor query(SQLiteDatabase db, String[] projectionIn,

            String selection, String[] selectionArgs, String groupBy,

            String having, String sortOrder, String limit) {

                     log(" query1() <-wlq->");

        if (mTables == null) {

            return null;

        }

 

        String sql = buildQuery(

                projectionIn, selection, selectionArgs, groupBy, having,

                sortOrder, limit);

                     log(" query1() sql="+sql+"<-wlq->");

        if (Log.isLoggable(TAG, Log.DEBUG)) {

            Log.d(TAG, "Performing query: " + sql);

        }

        return db.rawQueryWithFactory(

                mFactory, sql, selectionArgs,

                SQLiteDatabase.findEditTable(mTables));

    }


frameworks\base\core\java\android\database\sqlite\SQLiteDatabase.java

public Cursor rawQueryWithFactory(

            CursorFactory cursorFactory, String sql, String[] selectionArgs,

            String editTable) {

        long timeStart = 0;

 

        if (Config.LOGV || mSlowQueryThreshold != -1) {

            timeStart = System.currentTimeMillis();

        }

 

        SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable);

 

        Cursor cursor = null;

        try {

            cursor = driver.query(

                    cursorFactory != null ? cursorFactory : mFactory,

                    selectionArgs);

        } finally {

            if (Config.LOGV || mSlowQueryThreshold != -1) {

 

                // Force query execution

                if (cursor != null) {

                    cursor.moveToFirst();

                    cursor.moveToPosition(-1);

                }

 

                long duration = System.currentTimeMillis() - timeStart;

 

                if (Config.LOGV || duration >= mSlowQueryThreshold) {

                    Log.v(SQLiteCursor.TAG,

                          "query (" + duration + " ms): " + driver.toString() + ", args are "

                                  + (selectionArgs != null

                                  ? TextUtils.join(",", selectionArgs)

                                  : "<null>"));

                }

            }

        }

        return cursor;

    }

 

frameworks\base\core\java\android\database\sqlite\ SQLiteDirectCursorDriver.java

 

public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable) {

        mDatabase = db;

        mEditTable = editTable;

        //TODO remove all callers that end in ; and remove this check

        if (sql.charAt(sql.length() - 1) == ';') {

            Log.w(TAG, "Found SQL string that ends in ; -- " + sql);

            sql = sql.substring(0, sql.length() - 1);

        }

        mSql = sql;

    }


public Cursor query(CursorFactory factory, String[] selectionArgs) {

        // Compile the query

        SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, 0, selectionArgs);

 

        try {

            // Arg binding

            int numArgs = selectionArgs == null ? 0 : selectionArgs.length;

            for (int i = 0; i < numArgs; i++) {

                query.bindString(i + 1, selectionArgs[i]);

            }

 

            // Create the cursor

            if (factory == null) {

                mCursor = new SQLiteCursor(mDatabase, this, mEditTable, query);

            } else {

                mCursor = factory.newCursor(mDatabase, this, mEditTable, query);

            }

 

            mQuery = query;

            query = null;

            return mCursor;

        } finally {

            // Make sure this object is cleaned up if something happens

            if (query != null) query.close();

        }

    }


frameworks\base\core\java\android\database\sqlite\ SQLiteQuery.java

/* package */ SQLiteQuery(SQLiteDatabase db, String query, int offsetIndex, String[] bindArgs) {

        super(db, query);

        mOffsetIndex = offsetIndex;

        mQuery = query;

        mBindArgs = bindArgs;

    }

 

frameworks\base\core\java\android\database\sqlite\ SQLiteCursor.java

public SQLiteCursor(SQLiteDatabase db, SQLiteCursorDriver driver,

            String editTable, SQLiteQuery query) {

        // The AbstractCursor constructor needs to do some setup.

        super();

 

        if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {

            mStackTraceElements = new Exception().getStackTrace();

        }

 

        mDatabase = db;

        mDriver = driver;

        mEditTable = editTable;

        mColumnNameMap = null;

        mQuery = query;

 

        try {

            db.lock();

 

            // Setup the list of columns

            int columnCount = mQuery.columnCountLocked();

            mColumns = new String[columnCount];

 

            // Read in all column names

            for (int i = 0; i < columnCount; i++) {

                String columnName = mQuery.columnNameLocked(i);

                mColumns[i] = columnName;

                if (Config.LOGV) {

                    Log.v("DatabaseWindow", "mColumns[" + i + "] is "

                            + mColumns[i]);

                }

   

                // Make note of the row ID column index for quick access to it

                if ("_id".equals(columnName)) {

                    mRowIdColumnIndex = i;

                }

            }

        } finally {

            db.unlock();

        }

    }

你可能感兴趣的:(Contacts联系人查询过程)