簡體   English   中英

來自錯誤線程的領域訪問Android Retrofit2 RxJava

[英]Realm access from incorrect thread Android Retrofit2 RxJava

我試圖將我的對象從Retrofit直接保存到Realm中,但始終收到錯誤:“來自錯誤線程的Realm訪問”。

這是我的代碼:

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

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

由於可觀察到的來自翻新,因此可以有兩種選擇:

  1. 如果在未指定調度程序的情況下創建了CallAdapter,則它將在調用Observable.subscribe的線程上執行。
  2. 如果CallAdapter是使用特定的調度程序創建的,它將在該線程上執行。

如果適用的選項與創建對象的線程不同,則將引發“來自錯誤線程的領域訪問”錯誤。

您應該在接收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使用Realm的UI線程實例進行查詢。

Realm受線程限制 ,這意味着您需要確保在獲得引用的同一線程上對Realm對象和realm實例進行調用。 你可能想使用的調度方法observeOn()RxAndroid ,以確保您撥打realm::executeTransaction()你得到了相同的線程上realm上的實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM