“内容提供者”与“ SQLite数据库”之间的确切区别


87

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

但是之后,

  1. “ Content-Provider”和“ SQLite Database”之间的确切区别是什么?
  2. 什么时候最好存储数据?

任何例子或帮助!

Answers:


134

我发现一个主要区别如下:

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

因此,如果您有need to share data between applications, you need to use the content provider model as recommended in Android.这篇文章,将介绍内容提供程序的基础知识以及如何实现它。

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

提供的信息真不错。


2
好像该链接现在已消失...不再查看该文章。如果您再次找到它,希望看到您所引用的文章。
prolink007,2012年

在2012年2月11日,链接http://www.devx.com/wireless/Article/41133起作用,
k3b

如果我们在流程中提供了以线程安全的方式在多个应用程序之间共享数据的机制,该怎么办?
Manohar

2
另一个附加的优点是,内容提供程序的每个操作都使用一个线程,因此多个线程无法像在sqlite情况下那样修改数据库
Rat-a-tat-a-tat Ratatouille 2014年

54

“ Content-Provider”和“ SQLite Database”之间的确切区别是什么?

ContentProvider是一个外观-您可以实现的API,它将数据库暴露给其他进程。它可以在数据存储在SQLite数据库的方式来实现,但它并没有要。

什么时候最好存储数据?

抽象地回答是不可能的。一般来说,除非需要使用,否则请ContentProvider使用数据库。


26
我更喜欢使用ContentProvider,因为它是对SQL的很好的抽象。您还可以与CursorAdapter和自动重新查询配合使用。
亚历山大

26

我已经用数千个使用简单的SQLite方法的用户制作了许多优秀的应用程序。但这是前一段时间,我不得不手动编写许多代码,现在ContentProvider可以轻松地处理它们。那时我不赞成使用Content Providers,因为它似乎只会增加代码的复杂性。

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

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

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


我当时想将代码转换为内容提供者,但现在我想保留它。
Mohammed Subhi Sheikh Quroush 2014年

现在,您还可以添加Android的“房间”库
Ravindra Kushwaha,

8

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

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

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

2.进行大量写操作时表现不错

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

产生一个新线程来进行导入,这样不会对其他线程造成不利影响,尤其是负责更新UI的线程;在每次导入的末尾短暂地暂停和暂停,以提供需要更多使用同步方法的其他线程的机会。

3.内容提供商有时会迫使您横向思考

Android中的内容提供者的工作方式是在代码的其余部分和基础数据库之间提供抽象层。据我所知,这主要是由于事实,内容提供商可以从数据库以外的地方访问数据。

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

从侧面考虑该查询,也许您可​​以通过替代查询并从游标访问结果来获取所需的数据;并使用URI正常访问数据,并使用与特定查询匹配的特殊URI,以应对那些没有替代选择的任务。


根据ContentProvider,必须由多个线程一次调用必须实现的ContentProvider的六个抽象方法,因此必须将它们实现为线程安全的。抽象类ContentProvider不是特定代码例外的原因,而是实现。遵循进程和线程来实现ContentProvider的线程安全方法。
StahlRat

5

当您要在应用程序之间共享数据时,将使用内容提供程序。

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



3

我在寻找相同疑问的同时阅读了此答案,因此想与他人分享。它指出 -

优良作法是在数据上提供额外的抽象级别,以使内部更改更容易。如果您决定以后更改基础数据库结构怎么办?如果使用ContentProvider,则可以在其中包含所有结构更改,就好像您没有使用任何内容更改一样,您必须更改受结构更改影响的所有代码区域。此外,能够重用相同的标准API来访问数据,而不是通过低级访问数据库来乱扔代码,这是很好的。

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


3

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.