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

Amr*_*med 7 android android-widget android-database android-room android-architecture-components

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

这里的问题是 ViewModelProvider 需要一个片段或活动来处理..

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

这在应用程序小部件类中不可用,所以怎么做?

Aar*_*Lee 5

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

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

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


Jav*_*avi 5

我知道这已经有一段时间了,但我刚刚遇到这个问题,并想在其他成员 Aaron-dunigan-atlee 的启发下添加一些有用的东西。

基本上显示了数据库和 Dao 对象的去向……更重要的是,onDataSetChanged()显示了调用 Room 查询的方法。该示例用于记录应用程序来说明,正如上面所评论的,任何地方都不需要 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()
            { ...
Run Code Online (Sandbox Code Playgroud)

莎莎


Amr*_*med 4

所以在这里回答我自己..

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

    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);

}
Run Code Online (Sandbox Code Playgroud)