I have an issue about getting a list of favoriteBooks from RealmObject and fetch into App Widget. It works great with the app, but when I implement it with the widget, it shows error:
"Realm access from incorrect thread. Realm objects can only be accessed on the thread they were
created."
It would be great if you could help me to solve this problem with a clear example.
In my App MainActivity I have initialized Realm like that:
OnCreate(){
Realm.init(this);
RealmConfiguration config = new RealmConfiguration.Builder()
.name("favorite.realm")
.schemaVersion(1)
.deleteRealmIfMigrationNeeded()
.build();
Realm.setDefaultConfiguration(config);
}
And here is the code I have implemented into ListProvider.class of widget that produced error.
public class ListProvider implements RemoteViewsService.RemoteViewsFactory {
private Context context = null;
private int appWidgetId;
Realm realm;
RealmResults<FavoriteBooks> booksList;
RealmConfiguration config;
public ListProvider(Context context, Intent intent) {
this.context = context;
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
@Override
public void onCreate() {
Realm.init(context);
config = new RealmConfiguration.Builder()
.name("myfavorite.realm")
.schemaVersion(1)
.build();
realm = Realm.getInstance(config);
getDataFromRealm(context);
}
@Override
public void onDataSetChanged() {
getDataFromRealm(context);
}
@Override
public void onDestroy() {
realm.close();
realm = null;
}
@Override
public int getCount() {
return booksList == null ? 0 : booksList.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public RemoteViews getViewAt(final int position) {
final RemoteViews[] result = {null};
result[0] = new RemoteViews(context.getPackageName(), R.layout.widget_item);
if (booksList!=null) {
FavoriteBooks book = booksList.get(position);
result[0].setTextViewText(R.id.widgetText, book.getTitle());
}
return result[0];
}
@Override
public RemoteViews getLoadingView() {
return null;
}
@Override
public int getViewTypeCount() {
return 0;
}
private void getDataFromRealm(final Context context) {
booksList = realm.where(FavoriteBooks.class).findAll();
}
}
I actually wonder if Widgets run in a separate process.
Yes, you are right, My writing mistake. I mean How to sent OR get a List of RealmObject from MainActivity into Widget List Provider.
If anyone knows the answer please give me with an example.
I haven't worked with widgets, but I think the remote views are executed in a different process, therefore you might have to send detached copies to it.
@superssingh
Did you figure out how to address this problem? As documented here: https://realm.io/docs/java/latest/#using-a-realm-across-threads Realm objects are bound to the thread on which they are created. You can't move them to another thread. What you can do is either query for them in a new Realm instance, on the background thread or use copyFromRealm to create a "detached" copy which, of course, you can pass around like any other Java object
We haven't heard from you in quite a while, so I'm going to assume that you've found a solution and close this issue. If that's not correct, feel free to re-open it, create a new one or, best of all, open a question on Stack Overflow.
Yeah he needs detached copies because widgets run in a remote process.
Most helpful comment
I actually wonder if Widgets run in a separate process.