Reputation: 5
experiencing an error when trying to make new objects through a button with a relationship (one-to-many) from another page, using realm with recycler view to connect multiple to tasks to one note(the list of tasks)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task_activity);
final Realm mrealm = Realm.getDefaultInstance();
RealmResults<tItem> results = mrealm.where(tItem.class).findAll();
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
final tData data = new tData();
fbtn1 = (FloatingActionButton) findViewById(R.id.fbtn1);
recView = (RecyclerView)findViewById(R.id.task_list);
recView.setLayoutManager(layoutManager);
adapter = new tAdapter(results,this);
recView.setAdapter(adapter);
adapter.setIconClickCallback(this);
fbtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mrealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
final RealmResults<tItem> item2 = realm.where(tItem.class).findAll();
tItem item = mrealm.createObject(tItem.class);
UUID.randomUUID()
.toString();
taskData.add(item);
item.setTasks("to do list 1");
mrealm.copyToRealm(item);
}
});
}
});
adapter.notifyDataSetChanged();
RealmResults<tItem> tItem = mrealm.where(tItem.class).findAll();
Log.d("john", "new task ");
Log.d("", "path: " + mrealm.getPath());
}
});
}
the error points to this part of the code
tItem item = mrealm.createObject(tItem.class);
Upvotes: 0
Views: 1141
Reputation: 834
The best idea is to make a copy on you thread if you want to have it on this one.
Also, you should try to make request in a DAO or REPOSITORY pattern. I made a repository pattern like this :
public Observable<List<T>> query(final Specification spec) {
return Observable.create(new ObservableOnSubscribe<List<T>>() {
@Override
public void subscribe(@NonNull ObservableEmitter<List<T>> emitter) throws Exception {
Log.d(TAG, "OnSubscribe :: Thread id :"+Thread.currentThread().getId() + " name : "+Thread.currentThread().getName());
Realm realm = Realm.getDefaultInstance();
final RealmSpecification realmSpecification = (RealmSpecification) spec;
RealmResults<T> res = realmSpecification.toRealmResults(realm);
List<T> resList = realm.copyFromRealm(res);
realm.close();
if(res != null)
emitter.onNext(resList);
emitter.onComplete();
}
});
}
like that i can query my base from a thread to the main thread. All my queries uses these functions.
Upvotes: 0
Reputation: 81539
Your code is supposed to look like this:
Realm realm;
RealmResults<tItem> results;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task_activity);
realm = Realm.getDefaultInstance();
results = realm.where(tItem.class).findAll();
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
fbtn1 = (FloatingActionButton) findViewById(R.id.fbtn1);
recView = (RecyclerView)findViewById(R.id.task_list);
recView.setLayoutManager(layoutManager);
adapter = new tAdapter(results,this); // tAdapter extends RealmRecyclerViewAdapter
recView.setAdapter(adapter);
adapter.setIconClickCallback(this);
fbtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fbtn1Clicked();
}
});
}
private void fbtn1Clicked() {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
final RealmResults<tItem> items = realm.where(tItem.class).findAll();
tItem item = realm.createObject(tItem.class, UUID.randomUUID().toString();
item.setTasks("to do list 1");
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
if(realm != null) {
realm.close();
realm = null;
}
}
But your original error is that instead of
tItem item = mrealm.createObject(tItem.class);
you should have
tItem item = realm.createObject(tItem.class); // <-- background thread realm
Upvotes: 0
Reputation: 4024
Try creating tItem class using the realm instance instead of mRealm instance since that is the realm instance created for the async transaction
tItem item = realm.createObject(tItem.class);
Upvotes: 0
Reputation: 3282
Realm instance is thread - confined - you cannot make queries from another thread. This error occures, because you make query on a main thred and then attempt to use that query in async transaction, which will be executed on another thread:
final RealmResults<tItem> item2 = realm.where(tItem.class).findAll();
Upvotes: 0