2017-08-20 4 views
0

レルム3.5.0レルム:デバイス/エミュレータでなぜメソッドRealmChangeListener.onChange()毎回コールしないのですか?

Androidアプリケーション。

マイスニペット:

public class MainApp extends MultiDexApplication implements RealmChangeListener<RealmResults<PermissionOfferResponse>> { 

    private void loginAndConfig() { 
     String authUrl = "http://" + BuildConfig.OBJECT_SERVER_IP + ":" + BuildConfig.OBJECT_SERVER_PORT + "/auth"; 

     SyncUser.Callback callback = new SyncUser.Callback() { 
      @Override 
      public void onSuccess(SyncUser user) { 
        syncUser = user; 
        createPermissionOfferAndSyncWithROS(); 
      } 

      @Override 
      public void onError(ObjectServerError error) { 
       String errorMsg; 
       switch (error.getErrorCode()) { 
        case UNKNOWN_ACCOUNT: 
         errorMsg = "Account does not exists."; 
         break; 
        case INVALID_CREDENTIALS: 
         errorMsg = "User name and password does not match"; 
         break; 
        default: 
         errorMsg = error.toString(); 
       } 
       Log.w(TAG, "loginAndConfig: onError: result errorMsg = " + errorMsg); 
      } 
     }; 

     SyncCredentials syncCredentials = SyncCredentials.usernamePassword(
       BuildConfig.USER_NAME, BuildConfig.PASSWORD, false); 
     SyncUser.loginAsync(syncCredentials, authUrl, callback); 
    } 

    private void createPermissionOfferAndSyncWithROS() { 
     Realm managementRealm = syncUser.getManagementRealm(); 
     String offerToken = BuildConfig.REALM_OFFER_TOKEN; 
     final PermissionOfferResponse newPermissionOfferResponse = new PermissionOfferResponse(offerToken); 
     managementRealm.executeTransaction(new Realm.Transaction() { 
      @Override 
      public void execute(Realm realm) { 
       realm.insert(newPermissionOfferResponse); 
      } 
     }); 

     RealmResults<PermissionOfferResponse> realmResultPermissionOfferResponse = managementRealm.where(PermissionOfferResponse.class) 
       .equalTo("id", newPermissionOfferResponse.getId()) 
       .equalTo("statusCode", 0) // status > 0 is error 
       .findAll(); 
     realmResultPermissionOfferResponse.addChangeListener(this); 
    } 

    @Override 
    public void onChange(RealmResults<PermissionOfferResponse> permissionOfferResponse) { 
     PermissionOfferResponse permissionOfferResponse = permissionOfferResponse.first(); 
     realmURL = permissionOfferResponse.getRealmUrl(); 
    } 
} 

マイ手順:

  1. スタートのAndroidアプリ
  2. チェックがRealmChangeListener.onChange()がコール
  3. アンインストールAndroidアプリ
た方法 です

この3つのステップを繰り返す10 TIMES別のAndroidの構成上の

結果:

****************************************************** 
Emulator: Android 4.0.3, RAM 512 MB, VM Heap 48 MB 
method RealmChangeListener.onChange() call 10 times. 

****************************************************** 
Device: Android 4.3, RAM 700 MB 
method RealmChangeListener.onChange() call ONLY 7 times. 

****************************************************** 
Emulator: Android 6.0, RAM 512 MB, VM Heap 48 MB 
method RealmChangeListener.onChange() call ONLY 7 times. 

****************************************************** 
Emulator: Android 6.0, RAM 1 GB, VM Heap 48 MB 
method RealmChangeListener.onChange() call ONLY 5 times. 

****************************************************** 
Device: Android 6.0, RAM 2 GB 
method RealmChangeListener.onChange() call 10 times. 

質問:

  1. なぜ一部のデバイス/エミュレータ上の方法RealmChangeListener.onChange() 10回を呼び出しませんか?
  2. どうすれば修正できますか?

ありがとうございます。

答えて

1

でし作品:

private Set<RealmChangeListener<RealmResults<PermissionOfferResponse>> changeListeners = new HashSet<>(); 

    private void createPermissionOfferAndSyncWithROS() { 
     Realm managementRealm = syncUser.getManagementRealm(); 
     String offerToken = BuildConfig.REALM_OFFER_TOKEN; 
     final PermissionOfferResponse newPermissionOfferResponse = new PermissionOfferResponse(offerToken); 
     managementRealm.executeTransaction(new Realm.Transaction() { 
      @Override 
      public void execute(Realm realm) { 
       realm.insert(newPermissionOfferResponse); 
      } 
     }); 

     RealmResults<PermissionOfferResponse> realmResultPermissionOfferResponse = managementRealm.where(PermissionOfferResponse.class) 
       .equalTo("id", newPermissionOfferResponse.getId()) 
       .equalTo("statusCode", 0) // status > 0 is error 
       .findAll(); 

     class _RealmChangeListener implements RealmChangeListener<RealmResults<PermissionOfferResponse>> { 
      private RealmResults<PermissionOfferResponse> results; 

      public _RealmChangeListener(RealmResults<PermissionOfferResponse> results) { 
       this.results = results; 
       changeListeners.add(this); 
       results.addChangeListener(this); 
      } 

      @Override 
      public void onChange(RealmResults<PermissionOfferResponse> element) { 
       changeListeners.remove(this); 
       MainApp.this.onChange(element); 
      } 
     } 
     new _RealmChangeListener(realmResultPermissionOfferResponse); 
    } 

    public void onChange(RealmResults<PermissionOfferResponse> permissionOfferResponse) { 
     PermissionOfferResponse permissionOfferResponse = permissionOfferResponse.first(); 
     realmURL = permissionOfferResponse.getRealmUrl(); 
    } 
} 
+0

はい。あなたのソリューションは仕事です。ありがとう。問題は、ソリューションと異なるソリューションとは何ですか? – lmdic

+1

'_RealmChangeListener'クラスは、内部のRealmChangeListenerがフィールド参照として保持され、RealmChangeListenerへの呼び出しが発生するまで、' _RealmChangeListener'が強力な参照でセットに保持されることを保証します。変更リスナーが呼び出されます。 – EpicPandaForce

関連する問題