android - 在 Android 中使用内容提供程序公开多个表的最佳实践

标签 android sqlite android-contentprovider

我正在构建一个应用程序,其中有一张用于 Activity 的 table 和一张用于 field 的 table 。我希望能够授予其他应用程序访问此数据的权限。我有几个与此类问题的最佳实践相关的问题。

  1. 我应该如何构建数据库类? 我目前有 EventsDbAdapter 和 VenuesDbAdapter 的类,它们提供查询每个表的逻辑,同时有一个单独的 DbManager(扩展 SQLiteOpenHelper)来管理数据库版本、创建/升级数据库、访问数据库(getWriteable/ReadeableDatabase)。这是推荐的解决方案,还是将所有内容整合到一个类(即 DbManager)或分离所有内容并让每个适配器扩展 SQLiteOpenHelper 会更好?

  2. 我应该如何为多个表设计内容提供者? 扩展上一个问题,我应该为整个应用使用一个 Content Provider,还是应该为 Events 和 Venues 创建单独的提供程序?

我发现的大多数示例只处理单表应用程序,因此我希望您能在此处提供任何指点。

最佳答案

对您来说可能有点晚了,但其他人可能会觉得这很有用。

首先你需要创建多个 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 匹配器

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 block 来确定使用哪个表。这是我的插入代码

@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,依此类推。

关于android - 在 Android 中使用内容提供程序公开多个表的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3814005/

相关文章:

python - Django manager.py sql 创建空文件

android - 我什么时候应该在 ContentProvider 使用的 SQLiteOpenHelper 上调用 close()

android - 使用 _data 字段在 Android 数据库(自定义内容提供程序)中存储文件 - v1.6

连续不同列宽的Android TableLayout

android - 如何在 Android 中更新 WiFi 配置的频率?

mysql - 寻求软件建议外键

sqlite - Web 应用程序 SQLite 插入在 Chrome 11 中运行良好,但从 12 版开始就失败了。

android - 选择 contentProvider 中的前 n 行

Android工具栏白色与黑色

android - Dexguard:在没有 Android 应用程序的情况下加密 .so 文件