我想实现一个操作多个表的ContentProvider
。这是我到目前为止所尝试的。我编写了一个Java Interface
,它表示每个表应在其CRUD类中实现的CRUD操作。
public interface CRUDHandler {
//UPDATE
int update(Uri uri, ContentValues values, String selection,String[] selectionArgs);
//READ
Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) ;
//CREATE
Uri insert(Uri uri, ContentValues values);
//DELETE
int delete(Uri uri, String selection, String[] selectionArgs);
//get Mime type
String getType(Uri uri);
}
然后我写了一个abstract
class
,为UriMatcher
定义了一个静态ContentProvider
,因此extends
这个类应添加其Uri
的每个类标识它并为接口中的每个方法提供实现。
该课程如下:
public abstract class ApplicationCRUD implements CRUDHandler{
public static final UriMatcher sUriMatcher;
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
}
}
此外,我为每个extends
这个类的表创建了一个类,并将其Uri
添加到抽象类的UriMatcher
中。
以下是一个例子:
public class Table1CRUD extends ApplicationCRUD {
//Setup Projection Map for Table1
private static HashMap<String , String>sTable1ProjectionMap;
static {
sTable1ProjectionMap.put(ApplicationProviderMetaData.Table1MetaData._ID, ApplicationProviderMetaData.Table1MetaData.TABLE_NAME+"."+ApplicationProviderMetaData.Table1MetaData._ID);
sTable1ProjectionMap.put(ApplicationProviderMetaData.Table1MetaData.COL1, ApplicationProviderMetaData.Table1MetaData.TABLE_NAME+"."+ApplicationProviderMetaData.Table1MetaData.COL1);
sTable1ProjectionMap.put(ApplicationProviderMetaData.Table1MetaData.COL2, ApplicationProviderMetaData.Table1MetaData.TABLE_NAME+"."+ApplicationProviderMetaData.Table1MetaData.COL2);
}
public static final int INCOMING_SINGLE_URI_INDICATOR = 5;
public static final int INCOMING_COLLECTION_URI_INIDICATOR = 6;
static {
//standard URI
sUriMatcher.addURI(ApplicationProviderMetaData.AUTHORITY, "t1", INCOMING_COLLECTION_URI_INIDICATOR);
sUriMatcher.addURI(ApplicationProviderMetaData.AUTHORITY, "t1/#", INCOMING_SINGLE_URI_INDICATOR);
//here add your custom URI
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
}
现在我的ContentProvider
看起来像这样:
public class ApplicationProvider extends ContentProvider{
//Define TAG FOR EACH CLASS FOR DEBUGGING
private static final String TAG = "ApplicationProvider";
// Application CRUD Handlers use to support multiple tables inside the content provider
private static Table1CRUD table1CRUD;
private static Table2CRUD table2CRUD;
static {
table1CRUD = new Table1CRUD();
table2CRUD= new Table2CRUD();
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriMatchResult = ApplicationCRUD.sUriMatcher.match(uri);
//case Table1
if(uriMatchResult == Table1CRUD.INCOMING_COLLECTION_URI_INIDICATOR ||uriMatchResult == Table1CRUD.INCOMING_SINGLE_URI_INDICATOR )
{
return table1CRUD.delete(uri, selection, selectionArgs);
}
case Table2
else if(uriMatchResult == Table2.INCOMING_COLLECTION_URI_INDICATOR|| uriMatchResult ==Table2.INCOMING_SINGLE_URI_INDICATOR){
return table2CRUD.delete(uri, selection, selectionArgs);
}
else{
throw new IllegalArgumentException("Unknown Uri "+uri);
}
}
现在我使用SQLiteOpenHelper
作为ContentProvider
中的私有类
我在ContentProvider
中定义了它的一个实例。我应该修改接口并提供对象Dependency Injection
的每个CRUD方法,让每个函数使用它来访问数据库吗?我也想知道你对这种方法的看法:它足够好吗?它是否使我想要有效地做的事情?我可以做些什么修改来改进这种设计?
答案 0 :(得分:10)
如果您需要设计具有多个表的ContentProvider
,Google IO Schedule应用程序是一个很好的资源。听起来你想要做一些更复杂的事情,但也许它会有所帮助。
答案 1 :(得分:2)
我已经完成了开源项目,他们使用了多个表。您可以查看OpenIntents的各种项目,这里是similar question 我希望,它可以帮到你。
答案 2 :(得分:2)
为什么不以这种方式在内容提供商下制作多个表格。
假设您有两个名为A和B的表,它们的URI将是AUTHORITY / A,AUTHORITY / B
private static final int TableOne = 1;
private static final int TableTwo = 2;
private static final UriMatcher uriMatcher;
static{
uriMatcher.addUri(AUTHORITY,"A",TableOne);
uriMatcher.addUri(AUTHORITY,"B",TableTwo);
}
现在,您可以使用标准switch case实现重写方法,并正确映射到基础SQLite Database类的方法。