【问题标题】:ContentObserver for SQLite?SQLite 的 ContentObserver?
【发布时间】:2012-11-09 09:34:27
【问题描述】:

我一直在研究如何在 ListView 中显示我的数据库中的数据,同时跟踪数据库中的更改。

假设我有一个聊天应用程序,它显示了我所属的所有聊天室的 ListView。

适配器的查询是SELECT * FROM CHAT_ROOM ORDER BY UPTDATE_TIME,这意味着我希望首先显示具有最近活动的聊天室。正如我在ChatroomListActivity 中一样,收到了 3 号聊天室的消息,这意味着它现在需要成为 1 号聊天室并相应地重新排列单元格。

我知道加载器能够在后台重新查询,但正如我在previous question here 中回答的普通软件一样,加载器似乎还不够好。

是否有不同的机制来实时观察数据库变化?

【问题讨论】:

  • 这就是我喜欢 ContentProvider 的原因...您甚至可以从其他应用程序轻松插入/更新/删除(如果您允许的话),并且仍然可以了解其他应用程序的更改...
  • 在这种情况下,我必须使用数据库而不是内容提供者。
  • 为什么?您可以将数据库包装在 ContentProvider 中,然后在 update/inser/delete 中,您只需添加 getContext().getContentResolver().notifyChange(uri) 并且如果您在 query 中使用类似的 uri,则 query/Cursor 将被告知更改... ListView 支持此功能,因此您dot需要编写代码来刷新它
  • 检查this project ...它是我的助手库(带有示例),它在运行时从注释自动生成内容提供者
  • 我只是好奇,但我的回答有帮助吗?您找到问题的解决方案了吗?

标签: android observer-pattern android-sqlite android-cursoradapter


【解决方案1】:

我的做法

  • 类 GroupChatActivity
  • 类 MessageDataSource
  • 类 HandleNewMessage

GroupChat 活动有点明显。 MessageDataSource 从数据库插入和返回对象的类。 HandleNewMessage,这个不用我解释了。

  • GroupChat -> MessageDataSource -> getMessages()
  • HandleNewMessage -> MessageDataSource -> insertNewMessage();

您现在想要的是 GroupChat 和 HandleNewMessage 与 MessageDataSource 的同一实例对话。 所以你想要做的是在 MessageDataSource 中对 MessageDataSource 进行静态引用 示例:

 public class MessageDataSource {

    private static MessageDataSource mInstance;

    public static MessageDataSource getInstance(Context context) {
        if(mInstance == null){
            mInstance = new MessageDataSource(context);
        }
        return mInstance;
    }

    private MessageDataSource(Context context) {
        // NOTE: private constructor
    }
}

因为您将构造函数设为私有,所以您不能这样做

MessageDataSource data = new MessageDataSource(context);

因为构造函数是私有的,所以你必须这样做

MessageDataSource data = MessageDataSource.getInstance(context);

现在您的类 GroupActivityHandleNewMessage 可以与 MessageDataSource 的同一个实例进行通信,您可以创建一个自定义 Interface 来通知任何观察者.

例子:

    public class MessageDataSource {

    private static MessageDataSource mInstance;

    private SQLiteDatabase mDataBase;
    private SQLiteHelper DBHelper;
    private OnInsert mOnInsert;

    public static MessageDataSource getInstance(Context context) {
        if(mInstance == null){
            mInstance = new MessageDataSource(context);
        }
        return mInstance;
    }

    private MessageDataSource(Context context) {
        DBHelper = SQLiteHelper.getInstance(context);
    }

    public void createMessage(String JID, String message, String sender) {
        // Do DB Stuff here
        if(mOnInsert != null) {
            mOnInsert.onInsert(message);
        }
    }


    public void setOnInsertListener(final OnInsert onInsert) {
        mOnInsert = onInsert;
    }

    public static interface OnInsert {
        // Notify the observer that an insert has bin made
        public String onInsert(String message);
    }
}

您可以通过您认为需要的接口发送任意数量的对象。 现在,在您的 GroupChatActivity 中,您可以像设置 OnClickListener 的正常方式一样设置(在我的情况下) OnInserListener。或者你可以让你 Activity 实现接口。

此示例可能不符合您的确切需求,但要观察何时将新内容插入您的数据库并且您需要更新您的 listView,我认为这是要走的路,但如果有人找到更好的方法请评论。 :D

我希望这能让你朝着正确的方向前进。

亲切的问候。

【讨论】:

  • 令我困扰的是,您用于初始化 MessageDataSource 的上下文可能会变得无效(例如,活动重新启动)。因此,我会在 Application 类中创建 MessageDataSource 的实例。
  • 这绝对是另一种可能真正满足我需求的快速方法。我有一个前台服务(推送通知)来操作我的数据库,我使用优先级广播和 LocalBroadcastManager 将事件分派给活动。我将不得不将我的代码重构为这个模型。谢谢。
猜你喜欢
  • 1970-01-01
  • 2014-02-18
  • 1970-01-01
  • 1970-01-01
  • 2011-07-22
  • 1970-01-01
  • 1970-01-01
  • 2014-01-20
  • 1970-01-01
相关资源
最近更新 更多