android - realmio - realm objects can only be accessed from thread they were created -
question sound similar asked questions. have referred couldn't find solution problem i'm having.
private addcartitemdialog.cartitemlistener cartitemlistener = new addcartitemdialog.cartitemlistener() { @override public void onokclick(product cartitem, int quantity) { realm.executetransactionasync(new realm.transaction() { @override public void execute(realm bgrealm) { draftinvoice draftinvoice = bgrealm.where(draftinvoice.class).equalto("shop.id", shopid).findfirst(); invoiceitem invoiceitem = bgrealm.createobject(invoiceitem.class); invoiceitem.setprice(cartitem.getprice()); invoiceitem.setid(cartitem.getid()); invoiceitem.setquantity(quantity); invoiceitem.calculatetotal(); draftinvoice.getinvoiceitems().add(invoiceitem); updatecartitemcount(draftinvoice.getinvoiceitems().size()); } }, () -> { }, error -> { error.printstacktrace(); logger.e(error.getmessage()); }); } @override public void oncancelclick() { } };
error log shows following error -
08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: java.lang.illegalstateexception: realm access incorrect thread. realm objects can accessed on thread created. 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ io.realm.baserealm.checkifvalid(baserealm.java:449) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ io.realm.productrealmproxy.realmget$price(productrealmproxy.java:159) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ com.example.realshoptest.models.product.getprice(product.java:75) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ com.example.realshoptest.newinvoiceactivity$1$1.execute(newinvoiceactivity.java:76) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ io.realm.realm$1.run(realm.java:1187) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ io.realm.internal.async.bgpriorityrunnable.run(bgpriorityrunnable.java:34) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ java.util.concurrent.executors$runnableadapter.call(executors.java:422) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ java.util.concurrent.futuretask.run(futuretask.java:237) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1112) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:587) 08-28 15:10:25.214 4996-4996/com.example.realshoptest w/system.err: @ java.lang.thread.run(thread.java:818) 08-28 15:10:25.214 4996-4996/com.example.realshoptest e/testshopapp: realm access incorrect thread. realm objects can accessed on thread created.
error occurs @ line - invoiceitem.setprice(cartitem.getprice());
this piece of code seems work understanding not i'm accessing objects async'ly in same thread. missing here ?
public void onokclick(product cartitem, int quantity) {
this line receives product
ui thread's realm instance
realm.executetransactionasync(new realm.transaction() { @override public void execute(realm bgrealm) {
this call creates realm instance background thread
invoiceitem.setprice(cartitem.getprice());
cartitem
still belongs ui thread's realm instance, therefore cannot accessed on background thread
two solutions:
1.) send parameters background thread
public void onokclick(product cartitem, int quantity) { final long cartitemid = cartitem.getid(); final string price = cartitem.getprice(); realm.executetransactionasync(new realm.transaction() { @override public void execute(realm bgrealm) { draftinvoice draftinvoice = bgrealm.where(draftinvoice.class).equalto("shop.id", shopid).findfirst(); invoiceitem invoiceitem = bgrealm.createobject(invoiceitem.class); invoiceitem.setprice(price); invoiceitem.setid(cartitemid);
or
2.) requery object background thread's realm instance
public void onokclick(product cartitem, int quantity) { final long cartitemid = cartitem.getid(); realm.executetransactionasync(new realm.transaction() { @override public void execute(realm bgrealm) { product product = bgrealm.where(product.class).equalto("id", cartitemid).findfirst(); draftinvoice draftinvoice = bgrealm.where(draftinvoice.class).equalto("shop.id", shopid).findfirst(); invoiceitem invoiceitem = bgrealm.createobject(invoiceitem.class); invoiceitem.setprice(product.getprice()); invoiceitem.setid(cartitemid);
the second solution cleaner.
Comments
Post a Comment