2016-11-08 58 views
0

我試圖將我的對象從Retrofit直接存入領域,但總是得到錯誤:「領域從不正確的線程訪問」。從不正確的線程訪問領域Android Retrofit2 RxJava

這是我的代碼:

public class RestaurantRepositoryRetrofit implements IRestaurantRepository { 

private RestaurantApi mApi; 
private Realm realm; 
private IMapper<RestaurantJson,Restaurant> mRestaurantMapper; 

public RestaurantRepositoryRetrofit(IMapper<RestaurantJson, Restaurant> restaurantMapper) { 
    mApi = ApiProvider.getApi().create(RestaurantApi.class); 
    mRestaurantMapper = restaurantMapper; 
    // Get a Realm instance for this thread 
    realm = Realm.getDefaultInstance(); 
**} 
@Override 
public Observable<Restaurant> getRestaurantById(String restaurantId) {** 

    return mApi.getRestaurantById(restaurantId) 
      .map(new Func1<RestaurantJson, Restaurant>() { 
       @Override 
       public Restaurant call(RestaurantJson restaurantJson) { 
        realm.executeTransaction(new Realm.Transaction() { 
         @Override 
         public void execute(Realm realm) { 

          realm.copyToRealm(restaurantJson); 
         } 
        }); 
        return mRestaurantMapper.transform(restaurantJson); 
       } 
      }); 
    } 
} 

回答

1

您應該在接收API結果的後臺線程上打開Realm實例。

return mApi.getRestaurantById(restaurantId) 
     .map(new Func1<RestaurantJson, Restaurant>() { 
      @Override 
      public Restaurant call(RestaurantJson restaurantJson) { 
       try(Realm realm = Realm.getDefaultInstance()) { 
        realm.executeTransaction(new Realm.Transaction() { 
         @Override 
         public void execute(Realm realm) { 
          realm.copyToRealm(restaurantJson); 
         } 
        }); 
        return mRestaurantMapper.transform(restaurantJson); 
       } 
      } 
     }); 

但如果你打算回到有管理的RealmObject,你應該規劃出從已保存的代理ID,然後在主線程和查詢使用的ID領域的UI線程實例觀察。

1

realm = Realm.getDefaultInstance();將返回實例在其上創建該對象的線程。但Observable.map()在observable從其發送消息的線程上調用。

由於觀察到來自改造這可以是2種選擇:

  1. 如果CallAdapter時未指定調度,然後它會執行線程Observable.subscribe上創建被稱爲上。
  2. 如果CallAdapter是使用特定的調度程序創建的,它將在該線程上執行。

如果應用的選項與創建對象的選項不是同一個線程,則會拋出「來自錯誤線程的領域訪問」錯誤。

0

領域is thread confined,這意味着您需要確保您在Realm對象和realm實例上調用與您獲得參考的同一個線程上的實例。您可能希望使用中的調度方法以確保您在調用實例的同一線程上調用realm::executeTransaction()

相關問題