Android Architectural组件引入了在本地存储应用程序数据的新概念:Room.
以前使用ContentProvider
我们可以将数据库暴露给其他应用程序。我们如何对房间做同样的事情?
答案 0 :(得分:5)
如何在使用Room创建数据库时将数据库公开给其他应用程序?
最可能的答案:使用ContentProvider
。最大的区别在于您将使用RoomDatabase
及其getOpenHelper()
方法,而不是自己使用SQLiteOpenHelper
。您可以像以前一样使用与查询,插入,更新和删除相同的方法,但SupportSQLiteDatabase
的API与SQLiteDatabase
的API略有不同。
没有什么可以阻止您使用ContentProvider
使用@Dao
方法来恢复对象,但是您必须转身并将它们转换回Cursor
个对象(在这种情况下) query()
),这可能是乏味的。
与非房间数据库一样,您也可以通过任何其他适合您需求的IPC机制公开Room数据库,例如具有AIDL定义接口的绑定服务。 Room与IPC机制没有直接关系,但SQLiteDatabase
也没有。
答案 1 :(得分:1)
要将数据库公开给其他应用,您仍然需要ContentProvider
。但是,借助Room
,您可以在提供商应用程序中更轻松地访问数据库中的数据。
与Room配合使用的ContentProvider上的代码段。
您可以喜欢@lomza答案,但我建议使用@CommonsWare答案。因为它为客户提供了更大的查询数据的灵活性(如果您的业务拒绝,则可以使用@Dao进行查询)
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
@Nullable String[] selectionArgs, @Nullable String sortOrder) {
final int code = MATCHER.match(uri);
if (code == CODE_CHEESE_DIR) {
final Context context = getContext();
if (context == null) {
return null;
}
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(Cheese.TABLE_NAME);
String query = builder.buildQuery(projection, selection, null, null, sortOrder, null);
final Cursor cursor = SampleDatabase.getInstance(context)
.getOpenHelper()
.getWritableDatabase()
.query(query, selectionArgs);
cursor.setNotificationUri(context.getContentResolver(), uri);
return cursor;
} else {
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
并且假设您有这样的DAO。
@Dao
public interface ChesseDAO {
@Query("SELECT * FROM " + Chesse.TABLE_NAME)
LiveData<Cheese> read();
}
因此,您可以在应用程序中使用Room
或ContentProvider
来访问数据。
直接通过ContentProvider访问数据段。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
... someview setup...
// test
LoaderManager.getInstance(this).initLoader(1, null, mLoaderCallbacks);
}
private LoaderManager.LoaderCallbacks<Cursor> mLoaderCallbacks = new LoaderManager.LoaderCallbacks<Cursor>() {
String[] projections = new String[] {
Chesse.COLUMN_ID
Cheese.COLUMN_NAME
};
@NonNull
@Override
public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
return new CursorLoader(
YourActivity.this,
SampleContentProvider.URI_CHEESE,
projections,
null, null, null);
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor cursor) {
if (cursor != null && cursor.moveToFirst()) {
String chesseName = cursor.getString(cursor.getColumnIndex(Cheese.COLUMN_NAME));
Toast.makeText(YourActivity.this, chesseName, Toast.LENGTH_LONG).show();
}
}
@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
}
};
有关通过会议室访问数据的代码段
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
... someview setup...
// test
SampleDatabase.getInstance(this).chesse().read().observe(this, chesse -> {
Toast.makeText(YourActivity.this, chesse.name, Toast.LENGTH_LONG).show();
});
}
答案 2 :(得分:0)
检查GitHub上Room with Content Providers Sample的代码。使用Room with ContentProvider并没有多大的魔力。例如,insert()看起来像这样:
$(document).on('click', function (e) {
$target = $(event.target);
$target.addClass('active');
});