How to update Realm in multiple threads in Android?

I am trying to update realm instances of multiple threads. Instead of explaining everything, I created a flowchart as I understand it.

Here he is: enter image description here

So the problem is that I call notifyAppWidgetViewDataChanged() , it does not update the scope. I tried adding Realm.OnChangeListener to Service onCreate() , but the method is not called when changing the scope from the main thread. I also tried calling getDefaultRealmInstance() from the onGetViewFactory() . Same problem.

+5
source share
1 answer

Well, here is my "not very-efficient" solution:
From the Widget service, I override only one method to create a factory instance:

 @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return new WidFactory(getApplicationContext()); } 

And then the WidFactory class:

 class WidFactory implements WidService.RemoteViewsFactory { private static int myTasksSize; private Context context; private Realm realm; private RealmResults<Task> myTasks; WidFactory(Context context){ this.context = context; } @Override public void onCreate() { realm = Realm.getDefaultInstance(); myTasks = realm.where(Task.class).findAll(); myTasksSize = myTasks.size(); realm.close(); } @Override public void onDataSetChanged() { realm = Realm.getDefaultInstance(); realm.refresh(); myTasks = realm.where(Task.class).findAll(); myTasksSize = myTasks.size(); realm.close(); } @Override public RemoteViews getViewAt(int position) { realm = Realm.getDefaultInstance(); myTasks = realm.where(Task.class).findAll(); RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widgetrow_layout); final Task myTask = myTasks.get(position); rv.setTextViewText(R.id.widgetrow_text_id, myTask.getTaskText()); Intent fillInIntent = new Intent(context, WidShowTaskActivity.class); fillInIntent.putExtra("code", myTask.getCode()); realm.close(); rv.setOnClickFillInIntent(R.id.widgetrow_text_id, fillInIntent); return rv; } @Override public int getCount() { return myTasksSize; } @Override public RemoteViews getLoadingView() { return null; } @Override public int getViewTypeCount() { return 1; } @Override public long getItemId(int position) { return position; } @Override public boolean hasStableIds() { return true; } @Override public void onDestroy() { if (!realm.isClosed()){ realm.close(); } } } 

The bad thing with this solution is that I open and close the area 3 times: in onCreate() , onDatasetChanged() and in getViewAt() . Even worse, in general, I only need one instance for all widgets, so I wanted to transfer the area in the factory designer, so all plants use the same area. But 2 problems appeared:
1) I do not know how to โ€œupdateโ€ an instance of an area when the service starts; Android does not provide any methods.
2) I'm not sure how content providers work, but the factory class somehow spreads the work on multiple threads, but I don't like Realm. Not at all.
PS Please correct me if I'm wrong, somewhere I'm relatively new to Android and Realm.
And thanks again for your reply :) @G. Blake Mike

0
source

Source: https://habr.com/ru/post/1270055/


All Articles