将Room数据库公开给其他应用

cha*_*ait 2 android android-room android-livedata android-architecture-components

Android Architectural组件引入了新概念以将应用程序数据本地存储:Room。

以前使用a ContentProvider可以将数据库公开给其他应用程序。如何处理Room?

Com*_*are 5

当我们使用Room创建数据库时,如何将数据库公开给其他应用程序?

最可能的答案:使用ContentProvider。最大的不同是,您将使用您RoomDatabasegetOpenHelper()方法及其方法,而不是SQLiteOpenHelper自己动手。您可以使用与之前相同的查询,插入,更新和删除方法,尽管SupportSQLiteDatabaseAPI的方法略有不同SQLiteDatabase

没有什么阻止您ContentProvider使用使用@Dao方法来取回对象的,但是您必须转过身来将它们转换回Cursor对象(对于query()),这可能很乏味。

与非Room数据库一样,也欢迎您通过其他任何适合您需要的IPC机制来公开Room数据库,例如具有AIDL定义接口的绑定服务。Room与那些IPC机制没有直接关系,但是SQLiteDatabase


Jon*_*put 5

要将数据库公开给其他应用程序,您仍然需要ContentProvider。但是,借助 的帮助Room,您可以在提供商应用程序中更轻松地访问数据库中的数据。

ContentProvider 上与 Room 配合使用的片段。

你可以像@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

假设你有这样的 DAO。

@Dao
public interface ChesseDAO {

    @Query("SELECT * FROM " + Chesse.TABLE_NAME)
    LiveData<Cheese> read();

}
Run Code Online (Sandbox Code Playgroud)

因此,您在应用程序中可以访问数据,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) {

        }
    };
Run Code Online (Sandbox Code Playgroud)

有关通过 Room 访问数据的片段

@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();
    });
}
Run Code Online (Sandbox Code Playgroud)