将Android Sms Conversation标记为已读.Sql查询一次又一次地执行.(错误)



我正在尝试将android聊天线程中的所有消息标记为已读。我正在使用从AOSP项目复制的以下代码,但我的应用程序进入ANR,我在日志中不断收到以下消息。

ContentValues sReadContentValues = new ContentValues(2);
sReadContentValues.put("read", 1);
sReadContentValues.put("seen", 1);
private static final String UNREAD_SELECTION = "(read=0 OR seen=0)";
context.getContentResolver().update(threadUri, sReadContentValues, UNREAD_SELECTION, null);

日志消息在循环中重复

SQLiteConnectionPool:   executeForChangedRowCount started 152577ms ago - running, sql="UPDATE sms SET read=?,seen=? WHERE (read=0 OR seen=0) AND thread_id=1464"

自从我们分手以来,我一直在努力解决这个问题,但仍然没有成功。

这是一个旧线程,但我发现它在寻找如何正确利用ContentValue类型,它回答了我的问题,所以我会回答它…

循环日志消息:您只发布了代码的一小部分,所以我的最佳猜测是,每次在代码循环中选择消息时,您都会执行此更新。如果的情况,由于您试图在一次执行中更新整个线程,因此在收到所有所需消息并退出循环后,将这段代码移动到自己的方法中(假设它还没有)并只调用一次是合乎逻辑的。

应用程序进入ANR:尽管您发布的日志消息是"(read=0 OR seed=0)AND thread_id=1464",但您的代码在Where子句中只反映了"(read=0OR seed=0)"-这显然会引起一些挫折,因为您将尝试更新每个消息线程中的每一条消息。

虽然尝试更新所有现有线程的方法对处理器来说是非常耗时的,但如果您也在循环中执行此操作(正如您的日志消息所暗示的那样),那么您将收到一个ANR是非常有意义的,即使您包含了它只为单个thread_id运行的要求。。。

解决方案:请随意纠正我,但做出一些合乎逻辑的假设,我相信这是你的解决方案:

public void mainMethod()
{
    String threadId = "1464";
    Cursor cursor = getSomeMessages(threadId);
    if (cursor != null && cursor.moveToFirst()) {
        do {
            // ... Do something with the message
        } while (cursor.moveToNext());
        cursor.close();
    }
    updateMessagesToReadAndSeen(threadId);
}
private void updateMessagesToReadAndSeen(String threadId) {
    if (threadId != null && !threadId.isEmpty()) {
        ContentValues sReadContentValues = new ContentValues(2);
        sReadContentValues.put("read", 1);
        sReadContentValues.put("seen", 1);
        String UNREAD_SELECTION = "(read=0 OR seen=0) AND thread_id=" + threadId;
        context.getContentResolver().update(threadUri, sReadContentValues, UNREAD_SELECTION, null);
    }
}

我想,如果我必须为"范围友好的更改"提出一些建议,那就是将其分解为更灵活的方法。例如

private void UpdateContent(Uri uri, ContentValues values, String _where, String[] args) {
    _context.getContentResolver().update(uri, values, _where, args);
}

private static String UNREAD_UNSEEN_THREADID = "(read=0 OR seen=0) AND thread_id=";
private void updateMessagesReadAndSeen(String threadId, int setRead, int setSeen) {
    if (threadId != null && !threadId.isEmpty()) {
        ContentValues sReadContentValues = new ContentValues(2);
        sReadContentValues.put("read", setRead);
        sReadContentValues.put("seen", setSeen);
        UNREAD_UNSEEN_THREADID +=  threadId;
        UpdateContent(threadUri, sReadContentValues, UNREAD_UNSEEN_THREADID, null);
    }
}

我可以一直说下去,但这将使你在为产品开发新功能时有更大的灵活性。祝你好运

相关内容

最新更新