87

我已经为 Android 完成了 SQLite 数据库编程,但除了以下内容我对 Content-Provider 一无所知:“正如我提到的Android 开发者页面,Android SDK 解释了“内容提供者”,因为它用于存储和检索数据。”

但是之后,

  1. “内容提供者”和“SQLite 数据库”之间的确切区别是什么?
  2. 什么时候最好存储数据?

任何例子或帮助!

4

9 回答 9

137

我发现了一个主要区别,如下所示:

将数据存储在数据库中是一种持久化数据的好方法,但在 Android 中创建的数据库visible仅适用于创建它们的应用程序。也就是说,一个应用程序在Android上创建的SQLite数据库只能由该应用程序使用,不能由其他应用程序使用。

因此,如果您need to share data between applications, you need to use the content provider model as recommended in Android.在本文中介绍了内容提供者的基础知识以及如何实现内容提供者。

我在这个链接上找到了这篇文章

提供了非常好的信息。

于 2010-07-29T12:50:06.837 回答
55

“内容提供者”和“SQLite 数据库”之间的确切区别是什么?

ContentProvider是一个门面——一个你可以实现的 API,它将数据库暴露给其他进程。它可以通过将数据存储在 SQLite 数据库中的方式实现,但并非必须如此。

什么时候最好存储数据?

这是不可能抽象地回答的。一般来说,除非有什么要求您使用 a ,否则ContentProvider只需使用数据库即可。

于 2010-07-28T06:38:45.307 回答
27

我制作了许多优秀的应用程序,成千上万的用户都在使用它们,它们只是使用 SQLite 方法。但那是不久前的事了,我不得不手动编写大量代码,现在 ContentProvider 可以轻松处理这些代码。那时我不赞成使用 Content Providers,因为它似乎只会增加代码的复杂性。

然而在过去的几年里,随着 Android 的发展,我已经转向 ContentProvider,因为它可以节省时间并允许您做更多事情。我现在广泛使用它。一旦你编写了一个 Content Provider 类,你的生活就会变得容易得多。使用 ContentProvider,我可以轻松处理游标加载器、加载器回调和批量插入,过去我必须手动编写所有内容,但它仍然不能有效地工作。尤其是在更新列表视图时,现在只需一个 notifychange() 方法即可自动更新。这意味着现在我不必键入自己的侦听器并手动更新列表视图和适配器中的内容。另外,我不需要担心数据库的打开和关闭或内存泄漏。这一切都由内容提供者处理。我偶尔会遇到的唯一问题是您无法在 ContentProviders 中进行一些复杂的查询。在这种情况下,您仍然可以使用原始查询并使用老式的手动与 sqlite 交互。

如果您以前编写过自己的 DbAdapter、Helper 和 Observer,则可以安全地将它们带到您的新应用程序中,而无需花费时间将所有内容转换为 ContentProvider。但根据我的经验,我强烈建议转移到 ContentProvider。习惯它需要一些时间,但是一旦你有了它的经验,你就会坚持下去。

UPDATE 2017 我现在切换到Realm,这是在任何平台上使用数据库的更好方法。花几个小时学习它,并在您的应用程序开发生涯中节省无数时间。

于 2012-12-04T20:41:34.377 回答
8

1. 内容提供者不是线程安全的

默认情况下,内容提供者不是线程安全的。如果您有多个线程使用内容提供程序,您可以看到许多不同的异常被抛出和其他数据不一致。解决此问题的最简单方法是在内容提供者公开的每个公共方法上使用 synchronized 关键字。

这样,一次只有一个线程可以访问这些方法。

2. 在写大量的时候表现得很好

我需要在新的 Serval Maps 应用程序中将数据从二进制文件导入到应用程序内部使用的数据库中。为了做到这一点并与应用程序的其余部分配合使用,最好:

生成一个新线程来进行导入,这样其他线程就不会受到不利影响,尤其是负责更新 UI 的线程;并在每次导入结束时短暂暂停,以便为需要使用同步方法的其他线程提供更多机会。

3. 内容提供者有时会强迫你横向思考

Android 中内容提供程序的工作方式是在其余代码和底层数据库之间提供一个抽象层。据我所知,这主要是因为内容提供者可以从数据库以外的地方访问数据。

这意味着您无法在底层数据库上执行原始 SQL 查询,您需要使用传递给各种方法(如查询方法)的变量来指定 SQL 查询的各种组件。如果您的任务不适合内容提供者处理 SQL 的方式,您有两种选择:

横向考虑查询,也许您可​​以通过替代查询并从游标访问结果来获取您需要的数据;使用一个 URI 来正常访问数据,并使用一个特殊的 URI 来匹配那些没有替代方案的任务的特定查询。

于 2014-11-21T05:32:20.663 回答
5

当您想要跨应用程序共享数据时,使用内容提供程序。

如果您有一个应用程序附加的数据库,并且您希望另一个应用程序使用某些数据,您可以实现一个公开数据的内容提供程序

于 2010-07-28T06:49:17.473 回答
3

主要区别在于:当您的应用需要与其他应用共享信息时,请使用 Content-Provider。SQLite 仅为创建它的应用程序存储数据

于 2012-12-04T18:02:42.107 回答
3

我在寻找同样的疑问时阅读了这个答案,所以想分享它。它指出 -

为您的数据提供额外的抽象级别以使其更容易在内部进行更改是一种很好的做法。如果您决定稍后更改底层数据库结构怎么办?如果您使用 ContentProvider,您可以在其中包含所有结构更改,如果您不使用它,您将被迫更改受结构更改影响的所有代码区域。此外,能够重用相同的标准 API 来访问数据而不是乱扔代码以访问数据库是很好的。

因此,使用内容提供者将是一个好主意。

于 2015-05-12T11:19:50.177 回答
3

想想先进的内容管理系统。每个对象(页面、图像、新闻文章、事件项等)都有内容、地址、用户权限以及从系统的不同部分与之交互的方式。内容提供者为 Android 做这件事。您现在可以共享您可能存储在应用程序中的文件或图像。您还可以创建自定义的可共享对象,例如业务联系人、可编辑的便笺等。并指定安全性和默认应用程序以在您从任何其他应用程序打开此类对象时处理这些对象。

于 2015-06-28T13:34:24.720 回答
1

区别之一是内容提供者对内容观察者有平台支持。您需要为 SQLite 数据库实现自己的 Observable 模式。

如何使用 LoaderManager 自动重新查询

SQLite 的 ContentObserver?

于 2012-12-28T16:06:36.420 回答