12

我正在阅读文档,但我仍然不太确定。它说要使用getContentResolver(),但实际上并没有使用 CursorLoader。那么有没有办法通过CursorLoader呢?我知道该怎么做query()。步骤是否非常相似?即使只是一个准确解释这一点的链接也会有所帮助。

请注意,不要将我链接到 Google 文档,因为他们没有使用insert()ContentProvider 使用CursorLoader.

提前致谢!!

编辑:我可能应该提到我对此感到困惑的原因是因为调用了一个新的CursorLoader自动调用ContentProviders query()方法。但是我怎样才能为插入做同样的事情呢?

4

2 回答 2

40

查看我关于该主题的博客文章

内容解析器和内容提供者


CursorLoader它无关。

插入是一个完全不同的概念……CursorLoader. 与 结合使用时LoaderManager,它会在收到数据存储更改的通知CursorLoader时自动查询您的数据库并自行更新。ContentObserver它与将数据插入数据库的实际过程无关。

如何ContentResolver解决对 的请求

当您通过内容提供者向数据库中插入(或查询、更新或删除)数据时,您不会直接与提供者通信。相反,您使用该ContentResolver对象与提供者进行通信(请注意,ContentResolver在您的应用程序的 global 中 是一个私有实例变量Context)。更具体地说,执行的步骤顺序是:

  1. 你打电话getContentResolver().insert(Uri, ContentValues);

  2. ContentResolver对象决定了 Uri 的权限。

  3. ContentResolver请求中继到向授权注册的内容提供者(这就是您需要在 中指定授权的原因AndroidManifest.xml)。

  4. 内容提供者接收请求并执行指定的操作(在本例中insert)。插入数据的方式和位置取决于您如何实现insert方法(ContentProvider是一个抽象类,需要用户实现insertquerydeleteupdategetType)。

希望你至少能稍微了解一下。之所以涉及这么多步骤,是因为 Android (1) 允许应用程序拥有多个内容提供者,以及 (2) 需要确保应用程序可以安全地与其他第三方应用程序共享数据。(这不是因为它想混淆你,我保证)。

通过插入数据ContentProvider

ContentResolver既然您(希望)对如何将这些请求中继到内容提供者有了更好的了解,那么插入数据就相当简单了:

  1. 首先,确定您希望内容提供商匹配的 uri。这取决于您如何决定将 uri 与UriMatcher. 您拥有的每个 uri 代表将数据插入内部数据库的不同方式(即,如果您的应用程序有两个表,您可能会有两个 uri,每个表一个)。

  2. 创建一个新ContentValues对象并使用它来打包您希望发送给内容提供者的数据。该ContentValues对象将列名映射到数据值。在下面的示例中,列名是“column_1”,插入到该列下的值是“value_1”:

    ContentValues values = new ContentValues();
    values.put("column_1", "value_1");
    
  3. 收到后,内容提供者将(在您的情况下)将values对象传递给您SQLiteDatabase(通过SQLiteDatabase.insert(String table, String nullColumnHack, ContentValues values)方法)。与 不同的是ContentProvider,此方法是为您实现的……SQLiteDatabase知道如何处理values对象并将行插入数据库,返回插入行的行 ID,或者-1如果插入失败。

...这就是您将数据插入数据库的方式。


TL;博士

利用getContentResolver().insert(Uri, ContentValues);

于 2012-06-21T04:04:59.983 回答
2

将 Cursor 转换为 ContentValues 以便于数据库插入。

它说使用 getContentResolver(),但实际上并没有使用 CursorLoader

除了亚历克斯所说的之外,没有什么可以阻止您遍历Cursor返回的内容,将它们放入ContentValues 中,然后将其插入(例如,插入不同的数据库)。

只是我脑海中的一个例子(简单Cursor的两String列):

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    if (cursor.moveToFirst()) {
        ArrayList<ContentValues> values = new ArrayList<ContentValues>();
        do {
            ContentValues row = new ContentValues();
            DatabaseUtils.cursorStringToContentValues(cursor, fieldFirstName, row);
            DatabaseUtils.cursorStringToContentValues(cursor, fieldLastName, row);
            values.add(row);
        } while (cursor.moveToNext());
        ContentValues[] cv = new ContentValues[values.size()];
        values.toArray(cv);
        getContentResolver().bulkInsert(CONTENT_NAMES, cv);
    }
}

可能有更有效的方法来做到这一点(当然还有一些完整性检查),但这是我的第一个想法......

于 2012-06-21T04:20:13.923 回答