安卓 - SQLite内容提供程序和多线程

8

我对内容提供程序有些困惑。 如果我的应用程序中有多个活动,它们是否会得到各自的内容提供程序实例?它本质上只是一个类/接口吗?

在一个活动中,我将同时有许多线程写入数据库。我该如何处理允许一次只有一个线程进行写入?

我只需要捕获SQLiteDatabaseLockedException,使线程休眠然后重试吗? 还是有更好的方法?

当一个活动暂停/销毁时,数据库锁会被释放吗?如果是这样,我能否针对内容提供程序本身创建一个同步锁呢?

3个回答

4
如果您直接使用数据库,并且有多个写入器来自不同的线程,可能会遇到并发问题。 ContentProvider 可以同时被多个程序访问,因此您必须实现线程安全的访问。最简单的方法是在所有 ContentProvider 方法前面使用关键字 synchronized,以便只有一个线程可以同时访问这些方法。 如果您不需要 Android 同步数据访问到 ContentProvider,请在 AndroidManifest.xml 文件中的 <provider> 定义中设置 android:multiprocess=true 属性。这允许在每个客户端进程中创建一个提供程序实例,从而消除了执行进程间通信(IPC)的需要。

1
是的,它确实可以:http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html - Alex Lockwood
我不明白,如果我不设置multiprocess=true,那么Android会同步对ContentProvider的所有访问吗?在这种情况下,使用synchronized关键字就不必要了,是吗?在这种情况下,Femi的回答是正确的吗? - Gus

1

糟糕,我丢失了未注册用户的Cookie,因此无法将Femi的答案标记为正确。

文档http://developer.android.com/guide/topics/providers/content-providers.html证实了这一点:“当启动查询时,Android系统会识别查询目标的内容提供程序并确保其正常运行。系统实例化所有ContentProvider对象;您永远不需要自己处理它们。事实上,您根本不直接处理ContentProvider对象。通常,每种类型的ContentProvider只有一个实例。但是它可以与不同应用程序和进程中的多个ContentResolver对象进行通信。进程之间的交互由ContentResolver和ContentProvider类处理。”


1
如果您将您的问题/答案标记为需要版主关注并选择“其他”,您可以请求合并两个帐户。您可能还想考虑注册 :) - forsvarir

-3
如果您正在使用ContentProvider,我相信您不需要关心有多少线程在读写:Android平台会将所有调用编组到单个线程上,并解决同步和锁定问题。您只需打开数据库并读/写即可,其他人都通过ContentProvider接口进行通信。

6
由于这些ContentProvider方法可以从不同进程和线程的各种ContentResolver对象中调用,因此它们必须以线程安全的方式实现。 - kakopappa
嗯,声誉达到 50.5k 还回答这样的问题? - Marian Paździoch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接