会议室持久性库和内容提供商

时间:2017-10-18 07:23:27

标签: android architecture android-contentprovider android-room

过去几天我一直在花时间学习新的 Android架构组件。在跟进一些博客文章,文档和&教程,每个组件都清楚了。但突然间,我意识到我们的老朋友内容提供商。我可能听起来很傻,因为在写这个问题之前我花了很长时间搜索,我是唯一一个提出这个问题的人。我没有任何有用的解决方案。无论如何,如果我想用本地数据库构建一个应用程序,我现在显然会选择新的架构组件(实时数据,视图模型,房间),而不需要进一步思考这对于使应用程序10x强大有用非常有帮助。但是如果我希望我的数据库数据可以访问其他应用程序,例如To Widget如何将Content Provider与Room集成?

5 个答案:

答案 0 :(得分:23)

顺便说一下,我有同样的问题。我找到了一个样本here来回答我的问题。希望它和你一样。

简而言之,这是在DAO对象中,它将从Content Provider的query()方法调用。

/**
 * Select all cheeses.
 *
 * @return A {@link Cursor} of all the cheeses in the table.
 */
@Query("SELECT * FROM " + Cheese.TABLE_NAME)
Cursor selectAll();

注意它是如何返回Cursor个对象的。其他操作,您可以在样本中更详细地了解自己。

这是@CommonsWare在答案中的第3号选择,我认为。

答案 1 :(得分:11)

  

如果我想用本地数据库构建应用程序,我现在显然会选择新的架构组件(实时数据,视图模型,房间)

我不会使用术语"显然"那里。架构组件是一个选项,但不是必需的。

  

但如果我希望我的数据库数据可供其他应用程序访问,例如To Widget如何将Content Provider与Room集成?

应用小部件与ContentProvider无关。恕我直言极少数应用应通过ContentProvider向第三方展示数据库,而应用应仅使用ContentProvider内部用途。< / p>

话虽如此,你有几个选择:

  1. 请勿使用会议室,至少通过ContentProvider

  2. 展示会议桌。
  3. 将空间用于内部用途,然后通过调用ContentProvider

  4. 上的getOpenHelper(),为RoomDatabase使用经典的SQLite编程技术
  5. ContentProvider中使用会议室,编写自己的代码,从您检索的房间实体(MatrixCursor)建立query()或创建实体以供使用与其他操作(insert()update()delete()等)

答案 2 :(得分:4)

Room Library对Content Provider没有任何特别支持。您只能自己编写Content Provider,然后使用Room查询数据库。

如果您想使用Android体系结构组件并希望使用基于SQLite的内容提供商,请考虑使用Kripton Persistence Library:它允许从数据库查询生成实时数据为您生成内容提供商等等。至少但不是最后一个:为什么你只需编写where条件就必须编写整个SQL?

为了清楚起见,我是Kripton Persistence Library的作者。我之所以写这篇文章是因为我没有找到一个符合持久性管理所需要的独特库(是的,因为我喜欢编程)。

我用Kripton写了一个转换后的Google Content Provider Sample版本。你可以找到它here

只是为了简化阅读。使用Kripton,您只需要定义DAO接口。内容提供程序将由注释生成。在Kripton转换的相同DAO将是:

@BindContentProviderPath(path = "cheese")
@BindDao(Cheese.class)
public interface CheeseDao {

    @BindSqlSelect(fields="count(*)")
    int count();

    @BindContentProviderEntry
    @BindSqlInsert
    long insert(String name);

    @BindContentProviderEntry()
    @BindSqlSelect
    List<Cheese> selectAll();

    @BindContentProviderEntry(path = "${id}")
    @BindSqlSelect(where ="id=${id}")
    Cheese selectById(long id);

    @BindContentProviderEntry(path = "${id}")
    @BindSqlDelete(where ="id=${id}")
    int deleteById(long id);

    @BindContentProviderEntry(path = "${cheese.id}")
    @BindSqlUpdate(where="id=${cheese.id}")
    int update(Cheese cheese);

}

生成的Content Provider使用URI公开DAO的方法。为了清楚起见,我只在这里放置生成的JavaDoc(总是由Kripton)。

enter image description here

有关Kripton的更多信息,请访问its wikimy sitemy articles

答案 3 :(得分:2)

最新帖子,但我最近遇到了同样的问题。最终最终将同一Room数据库实例用于本地和内容提供者。

enter image description here

因此,应用程序本身照常使用Room Database,内容提供者使用“ open helper”“包装” Room Database,如下所示:

class DatabaseProvider : ContentProvider() {

    override fun onCreate(): Boolean {
        return true
    }

    override fun query(uri: Uri?, projection: Array<out String?>?, selection: String?, selectionArgs: Array<out String?>?, sortOrder: String?): Cursor? {
        val db = roomDatabase.openHelper.readableDatabase
        db.query(...)
    }

    override fun insert(uri: Uri?, values: ContentValues?): Uri? {
        val db = roomDatabase.openHelper.writableDatabase
        db.insert(...)
    }

    override fun update(uri: Uri?, values: ContentValues?, selection: String?, selectionArgs: Array<out String?>?): Int {
        val db = roomDatabase.openHelper.writableDatabase
        db.update(...)
    }

    override fun delete(uri: Uri?, selection: String?, selectionArgs: Array<out String?>?): Int {
        val db = roomDatabase.openHelper.writableDatabase
        db.delete(...)
    }

    override fun getType(uri: Uri?): String? {
    }
}

答案 4 :(得分:1)

你最好使用 SupportOpenHelper

public class MyContentProvider extends ContentProvider {
    public MyContentProvider() {
    }

    @Override
    public String getType(Uri uri) {
        // TODO: Implement this to handle requests for the MIME type of the data
        // at the given URI.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    UserDatabase database;

    @Override
    public boolean onCreate() {
        database = Room.databaseBuilder(getContext(), UserDatabase.class, "user.db").allowMainThreadQueries().build();
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
         return database.query(SupportSQLiteQueryBuilder.builder("user").selection(selection, selectionArgs).columns(projection).orderBy(sortOrder).create());
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return database.getOpenHelper().getWritableDatabase().update("user", 0, values, selection, selectionArgs);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return database.getOpenHelper().getWritableDatabase().delete("user", selection, selectionArgs);
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long retId = database.getOpenHelper().getWritableDatabase().insert("user", 0, values);
        return ContentUris.withAppendedId(uri, retId);
    }
}