Realm 3.5.0,Android 4.3,Gradle 4.1
任务:
为此,我选择了使用令牌的方法(PermissionOffers)。
这里是服务器端代码:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
instance = this;
RegistryUtil.getInstance(this);
init();
}
private void init() {
if (BuildConfig.DEBUG)
Log.d(TAG, "init: ");
Realm.init(this);
loginAndConfig();
}
private void loginAndConfig() {
SyncUser.Callback callback = new SyncUser.Callback() {
@Override
public void onSuccess(SyncUser user) {
Log.d(TAG, "loginAndConfig: onSuccess: Success_login");
setRealmDefaultConfiguration(user);
String token = RegistryUtil.getString(TOKEN);
Log.d(TAG, "onSuccess: loginAndConfig_token = " + token);
if (TextUtils.isEmpty(token)) {
Log.d(TAG, "onSuccess: No token ---> create new token...");
createToken(user, new PermissionOffer(REALM_NAME_URL, true, false, false, null));
}
}
@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();
}
}
};
SyncCredentials syncCredentials = SyncCredentials.usernamePassword(
BuildConfig.USER_NAME, BuildConfig.PASSWORD, false);
SyncUser.loginAsync(syncCredentials, AUTH_URL, callback);
}
private void setRealmDefaultConfiguration(SyncUser syncUser) {
SyncConfiguration syncConfig = new SyncConfiguration.Builder(syncUser, REALM_NAME_URL).build();
Realm.setDefaultConfiguration(syncConfig);
}
private void createToken(SyncUser syncUser, final PermissionOffer permissionOffer) {
Log.d(TAG, "createToken:");
Realm managementRealm = syncUser.getManagementRealm();
managementRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.insert(permissionOffer);
Log.d(TAG, "createToken: execute: Success realm_insert() NEW permissionOffer:\n"
+ "\npermissionOffer.getCreatedAt() = " + permissionOffer.getCreatedAt()
+ "\npermissionOffer.getId() = " + permissionOffer.getId()
+ "\npermissionOffer.getRealmUrl() = " + permissionOffer.getRealmUrl()
+ "\n\n"
);
RegistryUtil.setString(OFFER_ID, permissionOffer.getId());
}
});
Log.d(TAG, "createToken: Wait for server to handle the offer");
RealmResults<PermissionOffer> permissionOfferRealmResults = managementRealm
.where(PermissionOffer.class)
.equalTo("statusCode", 0)
.findAll();
permissionOfferRealmResults.addChangeListener(new RealmChangeListener<RealmResults<PermissionOffer>>() {
@Override
public void onChange(final RealmResults<PermissionOffer> offers) {
Log.d(TAG, "createToken: addChangeListener: onChange: offers_size = " + offers.size());
for (int index = 0; index < offers.size(); index++) {
PermissionOffer currentOffer = offers.get(index);
String currentOfferId = currentOffer.getId();
String realmUrl = currentOffer.getRealmUrl();
String realmName = realmUrl.substring(realmUrl.lastIndexOf('/') + 1).trim();
String token = currentOffer.getToken(); // must be send to client
Log.d(TAG, "onChange: Iterate all permission offers!"
+ "\nSummary report:\n"
+ "OFFER: createdAt = " + currentOffer.getCreatedAt()
+ ",id = " + currentOfferId
+ ",r = " + currentOffer.isMayRead()
+ ",w = " + currentOffer.isMayWrite()
+ ",statusCode = " + currentOffer.getStatusCode()
+ ",realmName = " + realmName
+ " ---> TOKEN = " + token);
String findOfferId = RegistryUtil.getString(OFFER_ID);
if (currentOfferId.equals(findOfferId)) {
Log.d(TAG, "onChange: This_is_my_offer ---> set token");
RegistryUtil.setString(TOKEN, token);
}
}
}
});
}
}
描述服务器端的步骤:
SyncConfiguration
并将其设为setDefaultConfiguration
。请参阅方法setRealmDefaultConfiguration
()所以现在在服务器端我需要获得新的令牌。
我的步骤(方法createToken()
):
getManagementRealm()
new PermissionOffer(REALM_NAME_URL, true, false, false, null)
Logcat片段:
createToken: execute: Success realm_insert() NEW permissionOffer:
permissionOffer.getCreatedAt() = Sun Sep 03 16:12:56 EEST 2017
permissionOffer.getId() = c5b66e73-07c3-4e3a-bc2b-d9a8486cd666
permissionOffer.getRealmUrl() = realm://myip:9181/~/myProjectRealm
等待服务器在下一个过滤器处理此新优惠( c5b66e73-07c3-4e3a-bc2b-d9a8486cd666):
RealmResults permissionOfferRealmResults = managementRealm.where(PermissionOffer.class).equalTo(“statusCode”,0).findAll();
5.服务器处理新优惠(方法onChange()
)后,我打印所有优惠
Logcat片段:
...
createToken: addChangeListener: onChange: offers_size = 10
onChange: Iterate all permission offers!
...
OFFER: createdAt = Sun Sep 03 15:48:37 EEST 2017,id = 47c71451-0505-499f-99e3-d5ad1ef0f40f,r = true,w = false,statusCode = 0,realmName = myRealm ---> TOKEN = fccc46bbe2354bae35d3ddb9e828700c:47c71451-0505-499f-99e3-d5ad1ef0f40f
OFFER: createdAt = Sun Sep 03 15:49:42 EEST 2017,id = 47e3a781-b103-4c68-ad9a-3bdcc34780fa,r = true,w = false,statusCode = 0,realmName = myRealm ---> TOKEN = fccc46bbe2354bae35d3ddb9e828700c:47e3a781-b103-4c68-ad9a-3bdcc34780fa
OFFER: createdAt = Sun Sep 03 16:12:56 EEST 2017,id = c5b66e73-07c3-4e3a-bc2b-d9a8486cd666,r = true,w = false,statusCode = 0,realmName = myProjectRealm ---> TOKEN = fccc46bbe2354bae35d3ddb9e828700c:c5b66e73-07c3-4e3a-bc2b-d9a8486cd666
onChange: This_is_my_offer ---> set token
...
你可以看到我的报价是最后一个( c5b66e73-07c3-4e3a-bc2b-d9a8486cd666 )
在logcat中将是:
onChange: This_is_my_offer ---> set token
现在我将这个新令牌( fccc46bbe2354bae35d3ddb9e828700c:c5b66e73-07c3-4e3a-bc2b-d9a8486cd666)发送给所有Android客户端。 OK!
此处客户端代码:
public class MainApp extends MultiDexApplication {
public void onCreate() {
super.onCreate();
initRealm();
}
private void initRealm() {
Realm.init(this);
String syncUserAsJson = RegistryUtil.getString(SYNC_USER);
if (BuildConfig.DEBUG)
Log.d(TAG, "initRealm: syncUserAsJson:\n" + syncUserAsJson + "\n\n");
if (syncUserAsJson != null) {
String syncUserJson = RegistryUtil.getString(SYNC_USER);
SyncUser syncUser = SyncUser.fromJson(syncUserJson);
initRealmConfigs(syncUser);
} else {
loginToRealm(BuildConfig.USER_NAME, BuildConfig.PASSWORD);
}
}
private void loginToRealm(final String userName, String password) {
if (BuildConfig.DEBUG)
Log.d(TAG, "loginToRealm: userName = " + userName);
// callback of SyncUser.loginAsync()
SyncUser.Callback callback = new SyncUser.Callback() {
@Override
public void onSuccess(SyncUser user) {
SyncUser syncUser = user;
if (BuildConfig.DEBUG)
Log.d(TAG, "loginToRealm: new Callback: onSuccess: >>>>>>>> Success login:\n"
+ "\nuser_name = " + userName
+ "\n- syncUser = " + syncUser
+ "\n- ---> initRealmConfigs()"
+ "\n\n");
RegistryUtil.setString(SYNC_USER, syncUser.toJson());
initRealmConfigs(syncUser);
}
@Override
public void onError(ObjectServerError error) {
if (BuildConfig.DEBUG)
Log.e(TAG, "loginToRealm: onError: ", 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();
}
if (BuildConfig.DEBUG)
Log.w(TAG, "loginToRealm: onError: result errorMsg = " + errorMsg);
}
};
SyncCredentials syncCredentials = SyncCredentials.usernamePassword(userName, password, false);
if (BuildConfig.DEBUG)
Log.d(TAG, "loginToRealm: ---> Try_to_login by: " + userName + " to address: " + AUTH_URL + " ...");
SyncUser.loginAsync(syncCredentials, AUTH_URL, callback);
}
private void initRealmConfigs(final SyncUser currentSyncUser) {
Log.d(TAG, "initRealmConfigs: currentSyncUser:\n" + currentSyncUser + "\n\n");
String tokenFromServer = "fccc46bbe2354bae35d3ddb9e828700c:c5b66e73-07c3-4e3a-bc2b-d9a8486cd666";
RealmService realmServiceOrganization = new RealmService(currentSyncUser, tokenFromServer);
realmServiceOrganization.setRealmServiceCallBack(new RealmService.RealmServiceCallBack() {
@Override
public void onSuccess(String newRealmURL) {
Log.d(TAG, "\n\ninitRealmConfigs: RealmServiceCallBack: onSuccess: Success get new realmURL:"
+ "\nnewRealmURL = " + newRealmURL
+ "\n\n"
);
Log.d(TAG, "initRealmConfigs: RealmServiceCallBack: onSuccess: ---> getSyncConfiguration() and loadOrganization()");
syncConfiguration = getSyncConfiguration(currentSyncUser, newRealmURL);
Log.d(TAG, "initRealmConfigs: RealmServiceCallBack: onSuccess: Success created syncConfigurationSG:\n"
+ syncConfiguration + "\n"
+ "\n ---> loadOrganization()\n\n"
);
}
});
}
private SyncConfiguration getSyncConfiguration(SyncUser syncUser, String realmURL) {
SyncConfiguration syncConfiguration = new SyncConfiguration.Builder(syncUser, realmURL)
// if use "waitForInitialRemoteData()" then call Realm.getInstanceAsync()
// or create new thread and call Realm.getDefaultInstance()
.waitForInitialRemoteData()
.build();
if (BuildConfig.DEBUG)
Log.d(TAG, "getSyncConfiguration: syncUser = " + syncUser.getIdentity() + ",realmURL = " + realmURL);
return syncConfiguration;
}
}
我获得Realm网址的服务:
public class RealmService {
private RealmService.RealmServiceCallBack realmServiceCallBack;
private Set<RealmChangeListener<RealmResults<PermissionOfferResponse>>> realmChangeListenersPermissionOfferResponse = new HashSet<>();
private static final String TAG = RealmService.class.getName();
public RealmService(SyncUser syncUser, String offerToken) {
Log.d(TAG, "RealmService_offerToken = " + offerToken);
createPermissionOfferAndSyncWithROS(syncUser, offerToken);
}
public void setRealmServiceCallBack(RealmServiceCallBack realmServiceCallBack) {
this.realmServiceCallBack = realmServiceCallBack;
}
// Call only if no realmURL
private void createPermissionOfferAndSyncWithROS(SyncUser syncUser, String offerToken) {
final Realm managementRealm = syncUser.getManagementRealm();
final PermissionOfferResponse newPermissionOfferResponse = new PermissionOfferResponse(offerToken);
Log.d(TAG, "createPermissionOfferAndSyncWithROS: Create newPermissionOfferResponse (id = "
+ newPermissionOfferResponse.getId() + ") from offerToken = " + newPermissionOfferResponse.getToken());
managementRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.insert(newPermissionOfferResponse);
Log.d(TAG, "createPermissionOfferAndSyncWithROS: Success realm_insert():" +
"\nSync newPermissionOfferResponse with ROS..."
+ "\nnewPermissionOfferResponse.getCreatedAt = " + newPermissionOfferResponse.getCreatedAt()
+ "\nnewPermissionOfferResponse.id = " + newPermissionOfferResponse.getId()
+ "\nnewPermissionOfferResponse.offerToken = " + newPermissionOfferResponse.getToken()
);
}
});
Log.d(TAG, "createPermissionOfferAndSyncWithROS: Wait for server to handle the offer with id = " + newPermissionOfferResponse.getId());
RealmResults<PermissionOfferResponse> realmResultPermissionOfferResponse = managementRealm.where(PermissionOfferResponse.class)
.equalTo("statusCode", 0)
.findAll();
// Guarantees that "RealmChangeListener.onChange()" will call EVERY time when application start first time!
class RealmChangeListenerImpl implements RealmChangeListener<RealmResults<PermissionOfferResponse>> {
private RealmResults<PermissionOfferResponse> results;
public RealmChangeListenerImpl(RealmResults<PermissionOfferResponse> results) {
if (BuildConfig.DEBUG)
Log.d(TAG, "createPermissionOfferAndSyncWithROS: RealmChangeListenerImpl:");
this.results = results;
realmChangeListenersPermissionOfferResponse.add(this);
// add listener for permissions change
results.addChangeListener(this);
}
// Call when Realm permissions was changed ---> receive new realmURL and setRealmSyncConfiguration()
@Override
public void onChange(RealmResults<PermissionOfferResponse> incomingPermissionOfferResponseList) {
Log.d(TAG, "onChange: FIRE onChange()");
int incomingPermissionOfferResponseListSize = incomingPermissionOfferResponseList.size();
Log.d(TAG, "createPermissionOfferAndSyncWithROS: RealmChangeListenerImpl: onChange:"
+ "\nRealm PERMISSION_WAS_CHANGED, incomingPermissionOfferResponseList.size = "
+ incomingPermissionOfferResponseListSize);
realmChangeListenersPermissionOfferResponse.remove(this);
if (incomingPermissionOfferResponseListSize > 0) {
Log.d(TAG, "createPermissionOfferAndSyncWithROS: RealmChangeListenerImpl: onChange:"
+ "\n---> RealmService.this.onChange()");
RealmService.this.onChange(incomingPermissionOfferResponseList);
} else {
Log.d(TAG, "createPermissionOfferAndSyncWithROS: RealmChangeListenerImpl: onChange:"
+ "\n---> EXIT");
}
}
}
new RealmChangeListenerImpl(realmResultPermissionOfferResponse);
}
private void onChange(RealmResults<PermissionOfferResponse> incomingPermissionOfferResponseList) {
PermissionOfferResponse incomingPermissionOfferResponse = incomingPermissionOfferResponseList.first();
String realmURL = incomingPermissionOfferResponse.getRealmUrl();
Log.d(TAG, "onChange: SUCCESS_GET_realmURL = " + realmURL + " ---> RealmServiceCallBack.onSuccess()");
realmServiceCallBack.onSuccess(realmURL);
}
public interface RealmServiceCallBack {
void onSuccess(String realmURL);
}
}
描述客户端的步骤:
新的permissionOfferResponse = e4a0da61-9a60-4734-8b9a-8a54d781e6c9
方法:
createPermissionOfferAndSyncWithROS()
newPermissionOfferResponse = new PermissionOfferResponse(offerToken);
并通过以下方式将其插入Realm:
realm.insert(newPermissionOfferResponse);
使用下一个过滤器:
RealmResults<PermissionOfferResponse> realmResultPermissionOfferResponse = managementRealm.where(PermissionOfferResponse.class)
.equalTo("statusCode", 0)
.findAll();
onChange(RealmResults<PermissionOfferResponse> incomingPermissionOfferResponseList)
。 (但不要打电话)Logcat片段:
RealmService(13701): RealmService_offerToken = fccc46bbe2354bae35d3ddb9e828700c:c5b66e73-07c3-4e3a-bc2b-d9a8486cd666
RealmService(13701): createPermissionOfferAndSyncWithROS: Create newPermissionOfferResponse (id = e4a0da61-9a60-4734-8b9a-8a54d781e6c9) from offerToken = fccc46bbe2354bae35d3ddb9e828700c:c5b66e73-07c3-4e3a-bc2b-d9a8486cd666
RealmService(13701): createPermissionOfferAndSyncWithROS: Success realm_insert():
RealmService(13701): Sync newPermissionOfferResponse with ROS...
RealmService(13701): newPermissionOfferResponse.getCreatedAt = Sun Sep 03 17:58:07 EEST 2017
RealmService(13701): newPermissionOfferResponse.id = e4a0da61-9a60-4734-8b9a-8a54d781e6c9
RealmService(13701): newPermissionOfferResponse.offerToken = fccc46bbe2354bae35d3ddb9e828700c:c5b66e73-07c3-4e3a-bc2b-d9a8486cd666
RealmService(13701): createPermissionOfferAndSyncWithROS: Wait for server to handle the offer with id = e4a0da61-9a60-4734-8b9a-8a54d781e6c9
RealmService(13701): createPermissionOfferAndSyncWithROS: RealmChangeListenerImpl:
正如您所看到的方法onChange(RealmResults<PermissionOfferResponse> incomingPermissionOfferResponseList)
不接听 !!!
结果我无法获得真实的信息。
为什么metohd onChange()
没有打电话?