短信ui分析--短信界面更新

本文深入探讨了短信界面更新机制,从核心类、provider分类到具体实现过程,包括数据库监听、主动更新及查询方法。同时介绍了sms表的设计技巧与触发器应用,以及总结了界面更新与数据库操作之间的紧密联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

短信界面更新

1、核心类

MessageListview 
MessageListAdapter
MmsProvider
MmsSmsProvider
SmsProvider

2、provider的分类

数据库的概况


 这是短信数据库的大致情况,对于短信而言最重要的表就是sms threads words

2.1  Smsprovider

uri:content://sms

该provider是针对sms表进行的增 删 改 查

2.2 MmsProvider

uri: content://mms

负责part、pdu表的增 删 改 查

2.3 MmsSmsProvider

 content://mms-sms/

主要负责threads的表的增 删 改 查;

且这个provider 是短信和彩信共有的,且与主界面更新相关

注意:同时对sms、mms都有相应的操作

3、具体实现

3.1 数据库监听

1)监听数据库改变

 mMsgListAdapter = new MessageListAdapter(this,null,mMsgListView,true, highlight);
        mMsgListAdapter.setOnDataSetChangedListener(mDataSetChangedListener);
        mMsgListAdapter.setMsgListItemHandler(mMessageListItemHandler);
        mMsgListView.setAdapter(mMsgListAdapter);

2)主动更新,当privider内容改变的时候

    private final MessageListAdapter.OnDataSetChangedListener
                    mDataSetChangedListener =new MessageListAdapter.OnDataSetChangedListener() {
        public void onDataSetChanged(MessageListAdapter adapter) {
            mPossiblePendingNotification =true;
        }
 
        public void onContentChanged(MessageListAdapter adapter) {
            startMsgListQuery();
        }
    };

3)查询该方法:

private void startMsgListQuery() {
        Uri conversationUri = mConversation.getUri();
        if (conversationUri ==null) {
            return;
        }
        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
            log("for " + conversationUri);
        }
        // Cancel any pending queries
        mBackgroundQueryHandler.cancelOperation(MESSAGE_LIST_QUERY_TOKEN);
        try {
            // Kick off the new query
            mBackgroundQueryHandler.startQuery(
                    MESSAGE_LIST_QUERY_TOKEN,null, conversationUri,
                    PROJECTION,null,null,null);
        } catch (SQLiteException e) {
            SqliteWrapper.checkSQLiteException(this, e);
        }
    }
这里的uri是:content://mms-sms/conversations/2

3.2 provider的实现

1)由于这里是界面的更新所以使用的是MmsSmsProvider,且看其查询短信的实现:

      case URI_CONVERSATIONS_MESSAGES:
                cursor = getConversationMessages(
                        uri.getPathSegments().get(1), projection, selection,
                        selectionArgs, sortOrder);
                break;

2)然后查看对应方法:

private CursorgetConversationMessages(
            String threadIdString, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        try {
            Long.parseLong(threadIdString);
        } catch (NumberFormatException exception) {
            Log.e(LOG_TAG,"Thread ID must be a Long.");
            return null;
        }
        String finalSelection = concatSelections(
                selection, "thread_id = " + threadIdString);
        String unionQuery = buildConversationQuery(
                projection, finalSelection, selectionArgs, sortOrder);
        returnmOpenHelper.getReadableDatabase().rawQuery(unionQuery,EMPTY_STRING_ARRAY);
    }

3)对于红色部分特别标示是因为,这里时区查询对应的数据库信息。请看下面是其核心代码:

private static String buildConversationQuery(String[] projection,
            String selection, String[] selectionArgs, String sortOrder) {
        String[] mmsProjection = createMmsProjection(projection);
        SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
        SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
        mmsQueryBuilder.setDistinct(true);
        smsQueryBuilder.setDistinct(true);
        mmsQueryBuilder.setTables(joinPduAndPendingMsgTables());
        smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
        String[] smsColumns = handleNullMessageProjection(projection);
        String[] mmsColumns = handleNullMessageProjection(mmsProjection);
        String[] innerMmsProjection = makeProjectionWithNormalizedDate(mmsColumns, 1000);
        String[] innerSmsProjection = makeProjectionWithNormalizedDate(smsColumns, 1);
 
        Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS);
        columnsPresentInTable.add("pdu._id");
        columnsPresentInTable.add(PendingMessages.ERROR_TYPE);
        String mmsSelection = concatSelections(selection,
                                Mms.MESSAGE_BOX +" != " + Mms.MESSAGE_BOX_DRAFTS);
        String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
                MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection,
                columnsPresentInTable, 0, "mms",
                concatSelections(mmsSelection, MMS_CONVERSATION_CONSTRAINT),
                selectionArgs, null,null);
        String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
                MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection,SMS_COLUMNS,
                0, "sms", concatSelections(selection, SMS_CONVERSATION_CONSTRAINT),
                selectionArgs, null,null);
        SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
        unionQueryBuilder.setDistinct(true);
        String unionQuery = unionQueryBuilder.buildUnionQuery(
                new String[] { smsSubQuery, mmsSubQuery },
                handleNullSortOrder(sortOrder), null);
        SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
        outerQueryBuilder.setTables("(" + unionQuery +")");
        return outerQueryBuilder.buildQuery(
                smsColumns, null,null,null,null, sortOrder,null);
这里是构建一个复合查询类似于:select *from sms,mms;即是会去查询出当前会话所有的彩信和短信,然后显示,所以这里的话一旦sms和mms provider的内容发生变化都会触发更新界面,这里一般是在发送和接收时会触发。

 4、sms表设计技巧

在sms表设计的时候有给该表创建一些触发器;
 // Updates threads table whenever a message is added to sms.
        db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " +
                   SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);
                           // Updates threads table whenever a message in sms is updated.
        db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" +
                   "  UPDATE OF " + Sms.DATE + ", " + Sms.BODY + ", " + Sms.TYPE +
                   "  ON sms " +
                   SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);
                           // Updates threads table whenever a message in sms is updated.
        db.execSQL("CREATE TRIGGER sms_update_thread_read_on_update AFTER" +
                   "  UPDATE OF " + Sms.READ +
                   "  ON sms " +
                   "BEGIN " +
                   SMS_UPDATE_THREAD_READ_BODY +
                   "END;");
       db.execSQL("CREATE TRIGGER delete_obsolete_threads_when_update_pdu " +
                   "AFTER UPDATE OF " + Mms.THREAD_ID + " ON pdu " +
                   "WHEN old." + Mms.THREAD_ID + " != new." + Mms.THREAD_ID + " " +
                   "BEGIN " +
                   "  DELETE FROM threads " +
                   "  WHERE " +
                   "    _id = old.thread_id " +
                   "    AND _id NOT IN " +
                   "    (SELECT thread_id FROM sms " +
                   "     UNION SELECT thread_id from pdu); " +
                   "END;");
大家可以看到当更新sms表或者其他动作时就会触发去更新

4、总结

   该文主要是针对界面更新展开来描述的,其数据库的作用远远不止于此。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值