如何使用ContentProvider的insert()方法通过CursorLoader将值正确插入到SQLite数据库中?

And*_*ndy 12 android android-contentresolver android-contentprovider android-loadermanager android-cursorloader

我正在阅读文档,但我仍然不太确定.它说要使用getContentResolver(),但那时确实没有使用CursorLoader.那么有办法实现CursorLoader吗?我知道如何做到这一点query().步骤非常相似吗?即使只是一个可以解释这一点的链接也会有所帮助.

请注意,请勿将我链接到Google文档,因为他们没有使用insert()ContentProvider使用方法的示例CursorLoader.

提前致谢!!

编辑:我应该提到我与此混淆的原因是因为调用一个新的CursorLoader自动调用ContentProviders query()方法.但是如何才能为插入做同样的事情呢?

Ale*_*ood 39

看看我关于这个主题的博文:

内容解析器和内容提供商


CursorLoader有什么用它做.

插入是一个完全不同的概念...它绝对没有做的CursorLoader.与s一起使用时LoaderManager,会CursorLoader自动查询数据库,并在ContentObserver收到数据存储区更改通知时自行更新.它与将数据插入数据库的实际过程无关.

如何ContentResolver解决请求

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

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

  2. ContentResolver对象决定了Uri的权威.

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

  4. 内容提供者接收请求并执行指定的操作(在这种情况下insert).如何以及在哪里被插入的数据取决于你如何实现的insert方法(ContentProvider是一个抽象类,需要用户来实现insert,query,delete,update,和getType).

希望你能够至少在一点点左右.之所以涉及这么多步骤,是因为Android(1)允许应用程序拥有多个内容提供商,(2)需要确保应用程序可以安全地与其他第三方应用程序共享数据.(这不是因为它想让你迷惑,我保证).

通过数据插入数据 ContentProvider

既然您(希望)能够更好地了解如何将ContentResolver这些请求转发给内容提供者,那么插入数据非常简单:

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

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

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

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


TL; DR

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

  • `insert`和`query`在**UI线程**上执行.我打算在本周末的某个时候写一些关于如何在单独的线程上执行昂贵的插入/查询的内容...我会告诉你的. (4认同)
  • 实际上,现在读完20次之后,你实际上是在说"CursorLoader"和"LoaderManager"与它没有任何关系.但我现在的问题是,这是在后台完成的,基本上是UI线程吗? (2认同)
  • @Andy,关于`Loader`s和`LoaderManager`的第一篇文章已经完成......下一篇文章将特别针对`LoaderManager`的工作原理.然后第三个将是非常具体的"Loader的工作方式......然后在那之后我可能会提供一些示例代码,说明如何将插入/删除/更新事务卸载到一个单独的线程......并且还提供了一些有关如何使用`Loader`从没有`ContentProvider`的SQLite数据库查询数据的细节.我需要停止这么懒.http://www.androiddesignpatterns.com/2012/07/loaders-and-loadermanager-background.html (2认同)
  • @AlexLockwood你说下面的"在线,让CursorLoader教程唯一的例子涉及查询......不插入,这就是为什么我想写一些事情",但你的博客文章居然不使用`CursorLoader`进行异步处理`完全插入().推荐的方法是使用`AsyncTask`,`AsyncQueryHandler`,扩展`AsyncTaskLoader`,还是其他方式? (2认同)