2016-08-29 42 views
1

問題類似於以前提出的問題。我已經提到這些,但無法找到我遇到的這個問題的解決方案。realmio - 領域對象只能從創建它們的線程訪問

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

這段代碼似乎從我的理解工作,但它並沒有因爲我訪問在同一個線程中async'ly對象。我在這裏錯過了什麼?

+0

您正在訪問cartItem –

+0

@TimCastelijns是的,謝謝你指出。我怎樣才能將'cartItem'傳遞給對話框,更新它的數量並讓它回到監聽器中? – Gimali

+0

傳遞id並查詢execute塊內的對象 –

回答

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

這條線從UI線程的境界實例收到Product

 realm.executeTransactionAsync(new Realm.Transaction() { 
      @Override 
      public void execute(Realm bgRealm) { 

此調用後臺線程

   invoiceItem.setPrice(cartItem.getPrice()); 

cartItem仍屬於UI線程的境界創建一個領域實例實例,因此它不能在後臺線程上訪問

兩個解決方案:

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

第二種解決方案更清潔。

相關問題