如何处理多个内容提供商?

17

我创建了两个内容提供程序,它们分别在同一SQLite数据库的两个不同表上工作。它们共享一个SQLiteOpenHelper实例,如Ali Serghini的帖子所描述。每个内容提供程序都在AndroidManifest.xml中注册,如下所示。

<provider
    android:name=".contentprovider.PostsContentProvider"
    android:authorities="com.example.myapp.provider"
    android:exported="false"
    android:multiprocess="true" >
</provider>
<provider
    android:name=".contentprovider.CommentsContentProvider"
    android:authorities="com.example.myapp.provider"
    android:exported="false"
    android:multiprocess="true" >
</provider>

每个内容提供者都定义了所需的内容URI,并提供了一个UriMatcher。
public class PostsProvider extends BaseContentProvider {

    private static final UriMatcher sUriMatcher = buildUriMatcher();
    private static final int POSTS = 100;
    private static final int POST_ID = 101;

    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = CustomContract.CONTENT_AUTHORITY;
        matcher.addURI(authority, DatabaseProperties.TABLE_NAME_POSTS, POSTS);
        matcher.addURI(authority, DatabaseProperties.TABLE_NAME_POSTS + "/#", POST_ID);
        return matcher;
    }

...

public class CommentsProvider extends BaseContentProvider {

    protected static final UriMatcher sUriMatcher = buildUriMatcher();
    protected static final int COMMENTS = 200;
    protected static final int COMMENT_ID = 201;

    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = CustomContract.CONTENT_AUTHORITY;
        matcher.addURI(authority, DatabaseProperties.TABLE_NAME_COMMENTS, COMMENTS);
        matcher.addURI(authority, DatabaseProperties.TABLE_NAME_COMMENTS + "/#", COMMENT_ID);
        return matcher;
    }

当我调用内容解析器插入文章时,会调用PostsContentProvider。但是当我尝试插入评论时,内容解析器却没有按预期引用CommentsContentProvider,而是调用了PostsContentProvider。结果是我在PostsContentProvider中抛出以下异常。
UnsupportedOperationException: Unknown URI: content://com.example.myapp.provider/comments

是否有可能输出当前已注册到内容提供程序的所有可用内容URI?


2
我创建了两个内容提供程序,它们可以在同一个SQLite数据库的两个不同表上工作。为什么不使用一个“在同一个SQLite数据库的两个不同表上工作”的ContentProvider呢?这就是Uri中路径的作用,允许您区分不同的表或类似的内容。 - CommonsWare
@CommonsWare 因为我计划在未来使用 SyncAdapter,而且我听说只有当提供程序是单独的提供程序时,其数据才能被同步。如果我错了,请纠正我。我很乐意阅读关于这个主题的任何文档。 - JJD
啊,好的。我还没有使用过SyncAdapter。如果你所说的限制存在,我会感到有些惊讶,但我不知道这种限制是否存在。抱歉! - CommonsWare
不会有任何冒犯。对于我来说,“SyncAdapter”仍然是一个神秘的东西。我进行了相当长时间的研究,但我仍然不确定是否可以使用“SyncAdapter”将“普通”数据与REST后端同步。 (https://dev59.com/kWfWa4cB1Zd3GeqPeCWa) - JJD
1个回答

33

android:authorities 需要对于每个内容提供者都是唯一的。文档在这里

内容:方案标识数据属于内容提供程序,并且权威机构(com.example.project.healthcareprovider)标识特定提供程序。因此,该机构必须是唯一的。


2
我在看到这篇文章时就已经预料到了,但还是感谢您的确认。奇怪的是,目前的文档不再提到名称应该是唯一的了? - Martijn de Milliano
十年后,确认文档仍未提到权限应该是唯一的。然而,在一个例子中它确实说道:“com.example.project.healthcareprovider 权限标识了提供者本身”,这表面上意味着权限必须是唯一的,以便唯一地识别提供者。 - LarsH

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