我想访问我的小部件类内的Room DB,以根据存储的数据更新小部件。
这里的问题是ViewModelProvider需要一个片段或活动才能使用。
ViewModelProviders.of(fragment).get(YourViewModel.class);
在应用小部件类中不可用,怎么办?
答案 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