thread的产生
当和一个联系人进行交流时,会将产生的message进行归类到conversation,其判断依据是recipient:
android.provider.Telephony.java
/**
* This is a single-recipient version of
* getOrCreateThreadId. It's convenient for use with SMS
* messages.
*/
public static long getOrCreateThreadId(Context context, String recipient) {
Set<String> recipients = new HashSet<String>();
recipients.add(recipient);
return getOrCreateThreadId(context, recipients);
}
/**
* Given the recipients list and subject of an unsaved message,
* return its thread ID. If the message starts a new thread,
* allocate a new thread ID. Otherwise, use the appropriate
* existing thread ID.
*
* Find the thread ID of the same set of recipients (in
* any order, without any additions). If one
* is found, return it. Otherwise, return a unique thread ID.
*/
public static long getOrCreateThreadId(
Context context, Set<String> recipients) {
Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();
for (String recipient : recipients) {
if (Mms.isEmailAddress(recipient)) {
recipient = Mms.extractAddrSpec(recipient);
}
uriBuilder.appendQueryParameter("recipient", recipient);
}
Uri uri = uriBuilder.build();
//if (DEBUG) Log.v(TAG, "getOrCreateThreadId uri: " + uri);
Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
uri, ID_PROJECTION, null, null, null);
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
return cursor.getLong(0);
} else {
Log.e(TAG, "getOrCreateThreadId returned no rows!");
}
} finally {
cursor.close();
}
}
Log.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString());
throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
}
}
由query()进入URI_THREAD_ID,调用getThreadId()
com.android.providers.telephony.MmsSmsProvider.java
/**
* Return the thread ID for this list of
* recipients IDs. If no thread exists with this ID, create
* one and return it. Callers should always use
* Threads.getThreadId to access this information.
*/
private synchronized Cursor getThreadId(List<String> recipients) {
Set<Long> addressIds = getAddressIds(recipients);
String recipientIds = "";
if (addressIds.size() == 0) {
Log.e(LOG_TAG, "getThreadId: NO receipients specified -- NOT creating thread",
new Exception());
return null;
} else if (addressIds.size() == 1) {
// optimize for size==1, which should be most of the cases
for (Long addressId : addressIds) {
recipientIds = Long.toString(addressId);
}
} else {
recipientIds = getSpaceSeparatedNumbers(getSortedSet(addressIds));
}
if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
Log.d(LOG_TAG, "getThreadId: recipientIds (selectionArgs) =" +
/*recipientIds*/ "xxxxxxx");
}
String[] selectionArgs = new String[] { recipientIds };
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery(THREAD_QUERY, selectionArgs);
if (cursor.getCount() == 0) {
cursor.close();
Log.d(LOG_TAG, "getThreadId: create new thread_id for recipients " +
/*recipients*/ "xxxxxxxx");
insertThread(recipientIds, recipients.size());
db = mOpenHelper.getReadableDatabase(); // In case insertThread closed it
cursor = db.rawQuery(THREAD_QUERY, selectionArgs);
}
if (cursor.getCount() > 1) {
Log.w(LOG_TAG, "getThreadId: why is cursorCount=" + cursor.getCount());
}
return cursor;
}
调用insertThread()创建一个新的thread
/**
* Insert a record for a new thread.
*/
private void insertThread(String recipientIds, int numberOfRecipients) {
ContentValues values = new ContentValues(4);
long date = System.currentTimeMillis();
values.put(ThreadsColumns.DATE, date - date % 1000);
values.put(ThreadsColumns.RECIPIENT_IDS, recipientIds);
if (numberOfRecipients > 1) {
values.put(Threads.TYPE, Threads.BROADCAST_THREAD);
}
values.put(ThreadsColumns.MESSAGE_COUNT, 0);
long result = mOpenHelper.getWritableDatabase().insert("threads", null, values);
Log.d(LOG_TAG, "insertThread: created new thread_id " + result +
" for recipientIds " + /*recipientIds*/ "xxxxxxx");
getContext().getContentResolver().notifyChange(MmsSms.CONTENT_URI, null);
}