首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Android中使用内容提供者公开多个表的最佳实践

在Android中使用内容提供者公开多个表的最佳实践
EN

Stack Overflow用户
提问于 2010-09-28 22:49:36
回答 5查看 43.2K关注 0票数 91

我正在构建一个应用程序,其中有一个用于活动的表和一个用于场馆的表。我希望能够授予其他应用程序访问此数据的权限。我有几个与解决此类问题的最佳实践相关的问题。

  1. How我应该构造数据库类吗?我目前有EventsDbAdapter和VenuesDbAdapter的类,它们提供了查询每个表的逻辑,同时有一个单独的DbManager (扩展SQLiteOpenHelper)来管理数据库版本,创建/升级数据库,提供对数据库(getWriteable/ReadeableDatabase)的访问。这是推荐的解决方案吗,或者我会更好地将所有东西整合到一个类中(即,DbManager)或分离所有内容并让每个适配器扩展SQLiteOpenHelper?
  2. How是否应该为多个表设计内容提供程序?扩展前面的问题,我应该为整个应用程序使用一个内容提供程序,还是应该为事件和场所创建单独的提供程序?

我发现的大多数例子只涉及单表应用程序,所以我希望在这里有任何指示。

EN

回答 5

Stack Overflow用户

发布于 2010-12-06 02:04:36

这对你来说可能有点晚了,但其他人可能会发现这很有用。

首先,您需要创建多个CONTENT_URIs

public static final Uri CONTENT_URI1 = 
    Uri.parse("content://"+ PROVIDER_NAME + "/sampleuri1");
public static final Uri CONTENT_URI2 = 
    Uri.parse("content://"+ PROVIDER_NAME + "/sampleuri2");

然后扩展您的URI Matcher

private static final UriMatcher uriMatcher;
static {
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(PROVIDER_NAME, "sampleuri1", SAMPLE1);
    uriMatcher.addURI(PROVIDER_NAME, "sampleuri1/#", SAMPLE1_ID);      
    uriMatcher.addURI(PROVIDER_NAME, "sampleuri2", SAMPLE2);
    uriMatcher.addURI(PROVIDER_NAME, "sampleuri2/#", SAMPLE2_ID);      
}

然后创建您的表

private static final String DATABASE_NAME = "sample.db";
private static final String DATABASE_TABLE1 = "sample1";
private static final String DATABASE_TABLE2 = "sample2";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE1 =
    "CREATE TABLE IF NOT EXISTS " + DATABASE_TABLE1 + 
    " (" + _ID1 + " INTEGER PRIMARY KEY AUTOINCREMENT," + 
    "data text, stuff text);";
private static final String DATABASE_CREATE2 =
    "CREATE TABLE IF NOT EXISTS " + DATABASE_TABLE2 + 
    " (" + _ID2 + " INTEGER PRIMARY KEY AUTOINCREMENT," + 
    "data text, stuff text);";

不要忘记将第二个DATABASE_CREATE添加到onCreate()

您将使用switch-case模块来确定使用哪个表。这是我的插入代码

@Override
public Uri insert(Uri uri, ContentValues values) {
    Uri _uri = null;
    switch (uriMatcher.match(uri)){
    case SAMPLE1:
        long _ID1 = db.insert(DATABASE_TABLE1, "", values);
        //---if added successfully---
        if (_ID1 > 0) {
            _uri = ContentUris.withAppendedId(CONTENT_URI1, _ID1);
            getContext().getContentResolver().notifyChange(_uri, null);    
        }
        break;
    case SAMPLE2:
        long _ID2 = db.insert(DATABASE_TABLE2, "", values);
        //---if added successfully---
        if (_ID2 > 0) {
            _uri = ContentUris.withAppendedId(CONTENT_URI2, _ID2);
            getContext().getContentResolver().notifyChange(_uri, null);    
        }
        break;
    default: throw new SQLException("Failed to insert row into " + uri);
    }
    return _uri;                
}

您将需要划分deleteupdategetType等。无论您的提供商在哪里调用DATABASE_TABLE或CONTENT_URI,您都需要添加一个案例,并将DATABASE_TABLE1或CONTENT_URI1放在一个案例中,然后将#2放在下一个案例中,依此类推,以获得任意多个案例。

票数 115
EN

Stack Overflow用户

发布于 2010-10-01 12:09:13

我推荐查看Android2.x ContactProvider的源代码。(可以在网上找到)。它们通过提供专门的视图来处理跨表查询,然后您可以在后端对这些视图运行查询。在前端,调用者可以通过单个内容提供者通过各种不同的URI访问它们。您可能还想提供一个或两个类,用于保存表字段名和URI字符串的常量。这些类既可以作为API include提供,也可以作为类中的一部分提供,这将使消费应用程序更易于使用。

这有点复杂,所以你可能还想看看日历是怎么回事,以了解你需要做什么和不需要什么。

您应该只需要为每个数据库(而不是每个表)使用一个DB适配器和一个内容提供程序来完成大部分工作,但是如果您确实需要的话,也可以使用多个适配器/提供程序。这只会让事情变得更复杂。

票数 10
EN

Stack Overflow用户

发布于 2011-03-30 18:53:57

一个ContentProvider可以为多个表提供服务,但它们应该有一定的相关性。如果您打算同步您的提供商,这将会有所不同。如果你想要单独的同步,比如说联系人,邮件或日历,你将需要为每个人提供不同的提供程序,即使它们最终在相同的数据库中或与相同的服务同步,因为同步适配器直接绑定到特定的提供程序。

据我所知,每个数据库只能使用一个SQLiteOpenHelper,因为它将其元信息存储在数据库中的一个表中。因此,如果您的ContentProviders访问相同的数据库,您将不得不以某种方式共享Helper。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3814005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档