2016-03-06 43 views
0

我想通過將使用領域的改造observable返回的服務調用的響應保存到本地數據庫,試圖將改造2與RxJava和領域相結合。所以我得到一個異常說Realm從不正確的線程訪問。 這裏是我的代碼:java.lang.IllegalStateException:從不正確的線程訪問域。領域對象只能在創建它們的線程上訪問

徑1:

restApi.userEntityList() 
      .map(userEntityDataMapper::transformAllToRealm) 
      .doOnNext(userRealmModels -> { 
       if (userRealmModels != null){ 
        mRealm = Realm.getInstance(mContext); 
        mRealm.asObservable() 
          .map(realm -> mRealm.copyToRealmOrUpdate(userEntity)) 
          .subscribe(new Subscriber<Object>() { 
           @Override 
           public void onCompleted() { 

           } 

           @Override 
           public void onError(Throwable e) { 
            e.printStackTrace(); 
           } 

           @Override 
           public void onNext(Object o) { 
            Log.d("RealmManager", "user added!"); 
           } 
          }); 
       }}) 
      .map(userEntityDataMapper::transformAll) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Subscriber<List<User>>() { 
       @Override 
       public void onCompleted() { 
        hideViewLoading(); 
       } 

       @Override 
       public void onError(Throwable e) { 
        hideViewLoading(); 
        showErrorMessage(new DefaultErrorBundle((Exception) e)); 
        showViewRetry(); 
       } 

       @Override 
       public void onNext(List<User> users) { 
        showUsersCollectionInView(users); 
       } 
      }); 

開拓者2:

restApi.userEntityList() 
      .map(userEntityDataMapper::transformAllToRealm) 
      .doOnNext(userRealmModels -> { 
       if (userRealmModels != null) { 
        mRealm = Realm.getInstance(mContext); 
        mRealm.beginTransaction(); 
        mRealm.copyToRealmOrUpdate(userEntity); 
        mRealm.commitTransaction(); 
       } 
      }) 
      .map(userEntityDataMapper::transformAll) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Subscriber<List<User>>() { 
       @Override 
       public void onCompleted() { 
        hideViewLoading(); 
       } 

       @Override 
       public void onError(Throwable e) { 
        hideViewLoading(); 
        showErrorMessage(new DefaultErrorBundle((Exception) e)); 
        showViewRetry(); 
       } 

       @Override 
       public void onNext(List<User> users) { 
        showUsersCollectionInView(users); 
       } 
      }); 

的logcat:

W/System.err: java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created. 
at io.realm.BaseRealm.checkIfValid(BaseRealm.java:349) 
at io.realm.BaseRealm.commitTransaction(BaseRealm.java:291) 
at io.realm.Realm.commitTransaction(Realm.java:108) 
at com.zeyad.cleanarchitecturet.data.db.RealmManagerImpl.put(RealmManagerImpl.java:66) 
at com.zeyad.cleanarchitecturet.data.db.RealmManagerImpl.putAll(RealmManagerImpl.java:91) 
at com.zeyad.cleanarchitecturet.data.repository.datasource.CloudUserDataStore$2.call(CloudUserDataStore.java:36) 
at com.zeyad.cleanarchitecturet.data.repository.datasource.CloudUserDataStore$2.call(CloudUserDataStore.java:32) 
at rx.Observable$11.onNext(Observable.java:4445) 
at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:80) 
at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54) 
at rx.internal.operators.OperatorMerge$MergeSubscriber.emitScalar(OperatorMerge.java:477) 
at rx.internal.operators.OperatorMerge$MergeSubscriber.tryEmit(OperatorMerge.java:435) 
at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:228) 
at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:142) 
at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54) 
at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:113) 
at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:88) 
at rx.Observable$2.call(Observable.java:162) 
at rx.Observable$2.call(Observable.java:154) 
at rx.Observable$2.call(Observable.java:162) 
at rx.Observable$2.call(Observable.java:154) 
at rx.Observable$2.call(Observable.java:162) 
at rx.Observable$2.call(Observable.java:154) 
at rx.Observable$2.call(Observable.java:162) 
at rx.Observable$2.call(Observable.java:154) 
at rx.Observable$2.call(Observable.java:162) 
at rx.Observable$2.call(Observable.java:154) 
at rx.Observable$2.call(Observable.java:162) 
at rx.Observable$2.call(Observable.java:154) 
at rx.Observable$2.call(Observable.java:162) 
at rx.Observable$2.call(Observable.java:154) 
at rx.Observable.unsafeSubscribe(Observable.java:8098) 
at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62) 
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
at rx.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(ExecutorScheduler.java:98) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: java.util.ArrayList.class 
at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:187) 
at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:82) 
... 29 more 
+0

什麼方法'userEntityDataMapper :: transformAllToRealm'和'userEntityDataMapper :: transformAll'做 我通過重寫GSON生成器作出這樣改造的回報境界對象?另外'showUsersCollectionInView(users);'似乎沒有使用你的流中的任何值? –

+0

映射(userEntityDataMapper :: transformAllToRealm)用於將服務器響應轉換爲本地保存的領域對象。在doOnNext()這個領域對象被保存。在地圖(userEntityDataMapper :: transformAll)中,領域對象被轉換回POJO併發送到表示層。應在訂閱方法中收到要添加到showUsersCollectionInView(用戶)中的recyclerView。 問題是領域引發異常java.lang.IllegalStateException:領域訪問不正確的線程。領域對象只能在創建它們的線程上訪問 –

+0

可以包含logcat嗎? – Shmuel

回答

1

我發現瞭如何解決它。要將服務器響應從改進2保存到領域,然後傳遞到用戶界面。

Retrofit.Builder() 
      .baseUrl(RestApi.API_BASE_URL) 
      .client(okHttpClient) 
      .callbackExecutor(new JobExecutor()) 
      .addConverterFactory(GsonConverterFactory.create(new GsonBuilder() 
        .setExclusionStrategies(new ExclusionStrategy() { 
         @Override 
         public boolean shouldSkipField(FieldAttributes f) { 
          return f.getDeclaringClass().equals(RealmObject.class); 
         } 

         @Override 
         public boolean shouldSkipClass(Class<?> clazz) { 
          return false; 
         } 
        }).create())) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .build(); 

然後:

restApi.userRealmList() 
    .doOnNext(userRealmModels -> { 
     if (userRealmModels != null) { 
      Realm realm = Realm.getInstance(mContext); 
      realm.beginTransaction(); 
      realm.copyToRealmOrUpdate(userRealmModels); 
      realm.commitTransaction(); 
      realm.close(); 
     }}) 
    .map(userEntityDataMapper::transformAll) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(new Subscriber<List<User>>() { 
     @Override 
     public void onCompleted() { 
      hideViewLoading(); 
     } 

     @Override 
     public void onError(Throwable e) { 
      hideViewLoading(); 
      showErrorMessage(new DefaultErrorBundle((Exception) e)); 
      showViewRetry(); 
     } 

     @Override 
     public void onNext(List<User> users) { 
      showUsersCollectionInView(users); 
     } 
    }); 
0

我想你已經使用主線程創建的域對象和您正在另一個或後臺線程中使用它。如果是這樣,那麼在創建它們的同一個線程中使用它們。 即

((Activity)mContext).runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     // You code of realm goes here 
     if (userRealmModels != null) { 
       mRealm = Realm.getInstance(mContext); 
       mRealm.beginTransaction(); 
       mRealm.copyToRealmOrUpdate(userEntity); 
       mRealm.commitTransaction(); 
     } 
    } 
}); 
+0

我沒有訪問上下文,加上想法是在後臺運行 –

+0

在哪一行你會得到異常? –

+0

Trail 1 on line:日誌貓不會在我的代碼中返回一行,只是在領域庫中有一些異常 Trail 2 on line:mRealm.copyToRealmOrUpdate(userEntity); –

相關問題