Android-如何从小部件访问Room数据库

时间:2018-08-22 19:31:13

标签: android android-widget android-room android-architecture-components android-database

我想访问我的小部件类内的Room DB,以根据存储的数据更新小部件。

这里的问题是ViewModelProvider需要一个片段或活动才能使用。

  

ViewModelProviders.of(fragment).get(YourViewModel.class);

在应用小部件类中不可用,怎么办?

7 个答案:

答案 0 :(得分:1)

您无需访问ViewModel就可以访问Room。ViewModel只是MVVM体系结构的一个组成部分,就像MVC或MVP一样。没有ViewModel,您仍然可以访问Room,只需要一个上下文即可。

答案 1 :(得分:1)

所以在这里回答我的自我。

唯一可行的方法是使用上下文从抽象类获取数据库实例,并在没有ViewModelProviders类的情况下直接在后台线程中运行DAO查询

    new AsyncTask<Context, Void, List<Data>>(){
        @Override
        protected List<Quote> doInBackground(Context... context) {

            List<Data> List=null;
                AppDatabase db = AppDatabase.getDatabase(context[0]);
                List = db.DataModel().getData();


            return List;
        }

        @Override
        protected void onPostExecute(List<Quote> List) {
            super.onPostExecute(List);

            if(List != null){

                final Random random=new Random();
                for (int appWidgetId : appWidgetIds) {
                    updateAppWidget(context, appWidgetManager, appWidgetId, quoteList.get(random.nextInt(List.size())));
                }

            }

        }

    }.execute(context);

}

答案 2 :(得分:1)

如果使用RemoteViewsService填充窗口小部件UI,则可以通过在其onDataSetChanged()方法而不是AppWidgetProvider的onUpdate()方法中包含DAO查询来避免使用AsyncTask。 。如onDataSetChanged() documentation中所述,

  

...昂贵的任务可以在此方法中安全地同步执行。在此期间,旧数据将显示在小部件内。

这里的另一个优点是,您可以在应用程序的ViewModel观察者的AppWidgetManager.notifyAppWidgetViewDataChanged()方法中包含对onChanged()的调用;这将触发onDataSetChanged(),并且每次更改Room数据库时,窗口小部件都会更新,而不仅仅是在onUpdate()的固定时间间隔内更新。

答案 3 :(得分:1)

我知道已经有一段时间了,但是我只是遇到了这个问题,并且想在同事Aaron-dunigan-atlee的启发下添加一些有用的东西。

基本显示数据库和Dao对象的去向...,更重要的是,调用Room查询的onDataSetChanged()方法。 该示例是为一个笔记记录应用程序说明的,正如上面所评论的,任何地方都不需要AsyncTasks。

public class MyWidgetRemoteViewsService extends RemoteViewsService
{
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent)
    {
        return new MyRemoteViewsFactory(this.getApplicationContext(), intent);
    }

    class MyRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory
    {
        private NotesDao notesDao;
        private List<Note> allNotes;

        MyRemoteViewsFactory(Context context, Intent intent)
        {
            MyDb db;
            db = MyDatabase.getDatabase(context);
            notesDao = db.notesDao();
        }

        @Override
        public void onCreate() { }

        @Override
        public void onDataSetChanged()
        {
            allNotes = notesDao.getAllNotes();
        }

        @Override
            public int getCount()
            { ...

sasa

答案 4 :(得分:0)

完全可以,..您已经需要从后台线程进行此DAO查询,因此将上下文传递给AsyncTask来执行查询是一个很好的解决方案,但是请尝试在上下文的构造函数中传递上下文AsyncTask而不是将其传递给参数。

答案 5 :(得分:0)

您不需要ViewModel即可从Room访问数据。您可以从任何地方访问数据,唯一的收获是,当数据更改不起作用时,获得通知的强大功能。为此,只需向您的Dao对象添加一个方法即可,该方法返回一个简单的List而不是LiveData>。就是这样。

答案 6 :(得分:-1)

您可以编写一个Repository类,并使用它来异步访问Room数据库。

示例:https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#7