RealmObject实例被多次调用

时间:2016-01-30 21:37:32

标签: android realm rx-java rx-android

我正在使用Realm + Retrofit2 我正在尝试实施以下内容:

  1. UI向DataManger询问数据。
  2. DataManger返回缓存数据,并检查数据是否已过期,然后调用新数据。
  3. 在Realm NetworkManager中保存新数据时触发由UI捕获的用于更新数据的事件。
  4. 问题

    当NetworkHelper在Realm中保存数据时,由于RealmObjects的onChangeListeners而在commitTransaction()之后,DataManger onCall()部分中的代码再次执行,它再次调用NetworkHelper获取新数据,然后再次从网络中保存数据过程进入无限循环。我在多个点尝试了gitHubUser.removeChangeListeners()但它仍然无法正常工作。请指出任何从根本上错误或使用Realm实现的正确方法。

    已实施的代码如下:

    DataManager

     public Observable<GitHubUser> getGitHubUser(final String user){
    
        return databaseHelper.getGitHubUser(user).doOnNext(new Action1<GitHubUser>() {
            @Override
            public void call(GitHubUser gitHubUser) {
                if(gitHubUser==null || !isDataUpToDate(CACHE_TIME_OUT,gitHubUser.getTimestamp())){
                    if(gitHubUser!=null)
                        System.out.println("isDataUpToDate = " + isDataUpToDate(CACHE_TIME_OUT,gitHubUser.getTimestamp()));
                    networkHelper.getGitHubUserRxBus(user);
                }
            }
        });
    }
    

    DataBaseHelper

    public Observable<GitHubUser> saveGitHubUser(GitHubUser user, String userId) {
        realmInstance.beginTransaction();
        user.setUserId(userId);
        user.setTimestamp(System.currentTimeMillis());
        GitHubUser userSaved = realmInstance.copyToRealm(user);
        Observable<GitHubUser> userSavedObservable = userSaved.asObservable();
        realmInstance.commitTransaction();
        return userSavedObservable;
    }
    
    public Observable<GitHubUser> getGitHubUser(String user){
        System.out.println("DatabaseHelper.getGitHubUser");
        GitHubUser result = realmInstance.where(GitHubUser.class).contains("userId",user, Case.INSENSITIVE).findFirst();
        if(result != null){
            return result.asObservable();
        }else{
            return Observable.just(null);
        }
    }
    

    NetworkHelper

      public void getGitHubUserRxBus(final String user){
        System.out.println("NetworkHelper.getGitHubUserRxBus");
        retroFitService.user(user)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .flatMap(new Func1<GitHubUser, Observable<GitHubUser>>() {
                    @Override
                    public Observable<GitHubUser> call(GitHubUser gitHubUser) {
                        System.out.println("NetworkHelper.call");
                        return databaseHelper.saveGitHubUser(gitHubUser,user);
                    }
                }).subscribe(new Action1<GitHubUser>() {
            @Override
            public void call(GitHubUser gitHubUser) {
    
                if (rxBus.hasObservers()) {
                    System.out.println("NetworkHelper.call");
                    rxBus.send(gitHubUser);
                }
            }
        });
    }
    

    活动

      subscription.add(dataManager.getGitHubUser("gitHubUserName")
                .subscribe(new Subscriber<GitHubUser>() {
            @Override
            public void onCompleted() {
                System.out.println("LoginActivity.call" + " OnComplete");
            }
    
            @Override
            public void onError(Throwable e) {
                System.out.println("throwable = [" + e.toString() + "]");
            }
    
            @Override
            public void onNext(GitHubUser gitHubUser) {
                System.out.println("LoginActivity.call" + " OnNext");
                if (gitHubUser != null) {
                    sampleResponseText.setText(gitHubUser.getName() + " timestamp " + gitHubUser.getTimestamp());
                }
                onCompleted();
    
            }
        }));
    subscription.add(rxBus.toObserverable().subscribe(new Action1<Object>() {
            @Override
            public void call(Object o) {
                if(o instanceof GitHubUser){
                    GitHubUser gitHubUser = ((GitHubUser)o);
                    sampleResponseText.setText(gitHubUser.getName() + " time " + gitHubUser.getTimestamp());
                }
            }
        }));
    

    更新

    最后通过在DataManger中关注来解决它:

    return Observable.concat(databaseHelper.getGitHubUser(user).take(1),
                                 networkHelper.getGitHubUser(user))
                        .takeUntil(new Func1<GitHubUser, Boolean>() {
                            @Override
                            public Boolean call(GitHubUser gitHubUser) {
                                boolean result = gitHubUser!=null && isDataUpToDate(CACHE_TIME_OUT,gitHubUser.getTimestamp());
                                System.out.println("isDataUpToDate = " + result);
                                return result;
                            }
                        });
    

1 个答案:

答案 0 :(得分:0)

我认为你的代码中有一个循环:

1)您可以在networkHelper.getGitHubUserRxBus(user)中的RealmResults创建一个observable。每次更改可能影响它们的数据时,Realm observable都会发出。

2)从Realm检索用户后调用result.asObservable().first()

3)从网络中获取用户时,将其保存到Realm,这将触发1)中创建的Observable再次发出,这将创建您的周期。

要打破它,您可以在getGitHubUser()中执行{{1}}之类的操作,因为它只会发出一次然后完成,但如果可以接受,则取决于您的用例。