Gun*_*ium 89 sqlite android android-contentprovider
我正在构建一个应用程序,我有一个事件表和一个场地表.我希望能够授予其他应用程序访问此数据的权限.我有几个与此类问题的最佳实践相关的问题.
我应该如何构建数据库类? 我目前有EventsDbAdapter和VenuesDbAdapter的类,它们提供查询每个表的逻辑,同时有一个单独的DbManager(扩展SQLiteOpenHelper)来管理数据库版本,创建/升级数据库,提供对数据库的访问(getWriteable/ReadeableDatabase).这是推荐的解决方案,还是我最好将所有内容整合到一个类(即DbManager)或分离所有内容并让每个适配器扩展SQLiteOpenHelper?
我应该如何为多个表设计内容提供程序? 扩展上一个问题,我应该为整个应用程序使用一个内容提供程序,还是应该为事件和场地创建单独的提供程序?
我发现的大多数示例只涉及单表应用程序,所以我很感激这里的任何指针.
Opy*_*Opy 114
对你来说可能有点晚了,但其他人可能觉得这很有用.
首先,您需要创建多个CONTENT_URI
public static final Uri CONTENT_URI1 =
Uri.parse("content://"+ PROVIDER_NAME + "/sampleuri1");
public static final Uri CONTENT_URI2 =
Uri.parse("content://"+ PROVIDER_NAME + "/sampleuri2");
Run Code Online (Sandbox Code Playgroud)
然后展开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);
}
Run Code Online (Sandbox Code Playgroud)
然后创建表格
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);";
Run Code Online (Sandbox Code Playgroud)
不要忘了添加第二个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;
}
Run Code Online (Sandbox Code Playgroud)
您将需要devide了delete
,update
,getType
等无论您的供应商要求DATABASE_TABLE或CONTENT_URI你会在未来一和#2增加的情况下,并有DATABASE_TABLE1或CONTENT_URI1等了很多,你想要的.
Cha*_*s B 10
我建议查看Android 2.x ContactProvider的源代码.(可以在网上找到).它们通过提供专用视图来处理跨表查询,然后在后端运行查询.在前端,调用者可以通过单个内容提供者通过各种不同的URI访问它们.您可能还希望提供一个或两个类来保存表字段名称和URI字符串的常量.这些类既可以作为API包含提供,也可以作为类中的drop提供,并且可以使消费应用程序更容易使用.
它有点复杂,所以你可能还想查看日历如何以及了解你做什么和不需要什么.
每个数据库(不是每个表)只需要一个数据库适配器和一个内容提供程序来完成大部分工作,但如果您真的想要,可以使用多个适配器/提供程序.它只是让事情变得复杂一些.
一个ContentProvider
可以服务多个表,但它们应该有些相关.如果您打算同步提供商,这将有所不同.如果你想要单独的同步,比如说联系人,邮件或日历,你需要为它们各自提供不同的提供者,即使它们最终在同一个数据库中或者与同一个服务同步,因为同步适配器直接绑定到特定的提供者.
据我所知,每个数据库只能使用一个SQLiteOpenHelper,因为它将元信息存储在数据库的表中.因此,如果您ContentProviders
访问同一个数据库,则必须分享Helper.
注意:这是对Opy提供的答案的澄清/修改.
这种方法每个细分的insert
,delete
,update
,并getType
与switch语句的方法,以处理每个单独的表.您将使用CASE来标识要引用的每个表(或uri).然后每个CASE映射到您的一个表或URI.例如,对于您的应用程序使用的所有表,在CASE#1等中选择了TABLE1或URI1.
这是该方法的一个例子.这适用于插入方法.它与Opy的实现略有不同,但执行相同的功能.您可以选择您喜欢的样式.我还想确保即使表插入失败,insert也会返回一个值.在这种情况下,它返回一个-1
.
@Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB;
long id = 0;
switch (uriType){
case TABLE1:
sqlDB = Table1Database.getWritableDatabase();
id = sqlDB.insert(Table1.TABLE_NAME, null, values);
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH1 + "/" + id);
case TABLE2:
sqlDB = Table2Database.getWritableDatabase();
id = sqlDB.insert(Table2.TABLE_NAME, null, values);
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH2 + "/" + id);
default:
throw new SQLException("Failed to insert row into " + uri);
return -1;
}
} // [END insert]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
41727 次 |
最近记录: |