Realm: Why on Devices/Emulators method RealmChange

2019-08-24 11:52发布

Realm 3.5.0

Android application.

My snippet:

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

My steps:

  1. Start Android application
  2. Check is method RealmChangeListener.onChange() was call
  3. Uninstall Android app

I repeat this 3 steps 10 TIMES.

Results on different Android configurations:

******************************************************
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.

Questions:

  1. Why on some Devices/Emulators method RealmChangeListener.onChange() NOT call 10 times?
  2. How I can fix this?

Thanks.

标签: android realm
1条回答
对你真心纯属浪费
2楼-- · 2019-08-24 12:31

The following could work:

    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();
    }
}
查看更多
登录 后发表回答