2016-08-29 5 views
1

質問は以前に質問したのと同様です。私はそれらを参照しましたが、私が持っているこの問題の解決策を見つけることができませんでした。realmio - realmオブジェクトは、作成されたスレッドからのみアクセスできます

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() { 

     } 
    }; 

エラー・ログを示し、次のエラー -

08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err: java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created. 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at io.realm.BaseRealm.checkIfValid(BaseRealm.java:449) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at io.realm.ProductRealmProxy.realmGet$price(ProductRealmProxy.java:159) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at com.example.realshoptest.models.Product.getPrice(Product.java:75) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at com.example.realshoptest.NewInvoiceActivity$1$1.execute(NewInvoiceActivity.java:76) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at io.realm.Realm$1.run(Realm.java:1187) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at io.realm.internal.async.BgPriorityRunnable.run(BgPriorityRunnable.java:34) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest W/System.err:  at java.lang.Thread.run(Thread.java:818) 
08-28 15:10:25.214 4996-4996/com.example.realshoptest E/TestShopApp: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created. 

エラーは、この行で発生 - invoiceItem.setPrice(cartItem.getPrice());

コードのこの作品は、私の理解から動作するようですが、私はアクセスだとしてそれはありませんオブジェクトは同じスレッド内で非同期である。私はここで何が欠けていますか?

+0

あなたは、カートアイテムにアクセスしています –

+0

@TimCastelijnsはい、ありがとうございます。どのように 'cartItem'をダイアログに渡し、その量を更新してそれをリスナーに戻すことができますか? – Gimali

+0

代わりにidを渡して、executeブロック内のオブジェクトを照会します –

答えて

1
public void onOkClick(Product cartItem, int quantity) { 

この行はProduct

UIスレッドのレルムインスタンスから
 realm.executeTransactionAsync(new Realm.Transaction() { 
      @Override 
      public void execute(Realm bgRealm) { 

を受けて、バックグラウンドスレッド

   invoiceItem.setPrice(cartItem.getPrice()); 

cartItemはまだUIスレッドのレルムに属しているため、このコールは、レルムのインスタンスを作成しますしたがって、バックグラウンドスレッドではアクセスできません。

2種類の溶液:

1)のみバックグラウンドスレッド

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); 

または

2にパラメータを送信する)は、バックグラウンドスレッドのレルムインスタンスで

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); 
をオブジェクトを再クエリ

2番目のソリューションはよりクリーンです。

関連する問題