Android 中具有单例模式的领域:结构是否正确?
Realm with Singleton Pattern in Android : Correct structure or not?
目前我的代码中有以下 singleton
结构用于管理 Realm
交易。我需要知道以下单例结构的优缺点。通过这种方法,我将从我所有的活动和片段中将 updateClockModel()
称为 RealManager.getInstance().updateClockModel(...)
。
public class RealmManager {
private static final String TAG = "RealmManager";
private static RealmManager mInstance = null;
private final ThreadLocal<Realm> localRealm = new ThreadLocal<>();
public static RealmManager getInstance() {
if (mInstance == null)
mInstance = new RealmManager();
return mInstance;
}
public Realm openLocalInstance() {
Realm realm = Realm.getDefaultInstance();
if (localRealm.get() == null) {
localRealm.set(realm);
}
return realm;
}
public Realm getLocalInstance() {
Realm realm = localRealm.get();
if (realm == null) {
throw new IllegalStateException("No open Realms were found on this thread.");
}
return realm;
}
public void closeLocalInstance() {
Realm realm = localRealm.get();
if (realm == null) {
throw new IllegalStateException(
"Cannot close a Realm that is not open.");
}
realm.close();
if (Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()) <= 0) {
localRealm.set(null);
}
}
protected RealmManager() {
}
public void updateClockModel(ClockRLM clockRLM, OnRealmDatabaseListener mRealmListener) {
Realm mRealm = openLocalInstance();
mRealm.executeTransactionAsync(realm -> {
RealmResults<ClockRLM> result = realm.where(ClockRLM.class).equalTo("timeStamp", clockRLM.getTimeStamp()).findAll();
for (ClockRLM clockRLM1 : result) {
clockRLM1.setUploadedSuccess(true);
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
Log.d("Clocke ", "inserted TimeStamp " + clockRLM.getTimeStamp());
if (mRealmListener != null)
mRealmListener.isDatabaseOperationSuccess(clockRLM, true);
closeLocalInstance();
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
if (mRealmListener != null)
mRealmListener.isDatabaseOperationSuccess(clockRLM, false);
closeLocalInstance();
}
});
}
public void addClockModel(ClockRLM clockRLM, OnRealmDatabaseListener mRealmListener) {
Realm mRealm = openLocalInstance();
mRealm.executeTransactionAsync(realm -> realm.copyToRealm(clockRLM), new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
Log.d("Clocke ", "Inserted TimeStamp " + clockRLM.getTimeStamp());
if (mRealmListener != null)
mRealmListener.isDatabaseOperationSuccess(clockRLM, true);
closeLocalInstance();
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
closeLocalInstance();
}
});
}
}
它会工作,除了那些写的方法不能在后台线程上执行 - 只能在 ui 线程上执行 - 所以我会添加类似下面的方法
private void executeInTransaction(Realm.Transaction transaction) {
try {
Realm realm = openLocalInstance();
if(!realm.isAutoRefresh()) {
try {
boolean wasInTransaction = realm.isInTransaction();
if(!wasInTransaction) {
realm.beginTransaction();
}
transaction.execute(realm);
if(!wasInTransaction) {
realm.commitTransaction();
}
} catch(Throwable e) {
if(realm.isInTransaction()) {
realm.cancelTransaction();
}
}
} else {
realm.executeTransactionAsync(transaction);
}
} finally {
closeLocalInstance();
}
}
通过这种方式,您可以通过手动打开事务进行批量后台操作 + 从 UI 线程执行异步写入。
您需要进行一些调整才能添加 "success/failure" 侦听器,但基础知识已具备。
目前我的代码中有以下 singleton
结构用于管理 Realm
交易。我需要知道以下单例结构的优缺点。通过这种方法,我将从我所有的活动和片段中将 updateClockModel()
称为 RealManager.getInstance().updateClockModel(...)
。
public class RealmManager {
private static final String TAG = "RealmManager";
private static RealmManager mInstance = null;
private final ThreadLocal<Realm> localRealm = new ThreadLocal<>();
public static RealmManager getInstance() {
if (mInstance == null)
mInstance = new RealmManager();
return mInstance;
}
public Realm openLocalInstance() {
Realm realm = Realm.getDefaultInstance();
if (localRealm.get() == null) {
localRealm.set(realm);
}
return realm;
}
public Realm getLocalInstance() {
Realm realm = localRealm.get();
if (realm == null) {
throw new IllegalStateException("No open Realms were found on this thread.");
}
return realm;
}
public void closeLocalInstance() {
Realm realm = localRealm.get();
if (realm == null) {
throw new IllegalStateException(
"Cannot close a Realm that is not open.");
}
realm.close();
if (Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()) <= 0) {
localRealm.set(null);
}
}
protected RealmManager() {
}
public void updateClockModel(ClockRLM clockRLM, OnRealmDatabaseListener mRealmListener) {
Realm mRealm = openLocalInstance();
mRealm.executeTransactionAsync(realm -> {
RealmResults<ClockRLM> result = realm.where(ClockRLM.class).equalTo("timeStamp", clockRLM.getTimeStamp()).findAll();
for (ClockRLM clockRLM1 : result) {
clockRLM1.setUploadedSuccess(true);
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
Log.d("Clocke ", "inserted TimeStamp " + clockRLM.getTimeStamp());
if (mRealmListener != null)
mRealmListener.isDatabaseOperationSuccess(clockRLM, true);
closeLocalInstance();
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
if (mRealmListener != null)
mRealmListener.isDatabaseOperationSuccess(clockRLM, false);
closeLocalInstance();
}
});
}
public void addClockModel(ClockRLM clockRLM, OnRealmDatabaseListener mRealmListener) {
Realm mRealm = openLocalInstance();
mRealm.executeTransactionAsync(realm -> realm.copyToRealm(clockRLM), new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
Log.d("Clocke ", "Inserted TimeStamp " + clockRLM.getTimeStamp());
if (mRealmListener != null)
mRealmListener.isDatabaseOperationSuccess(clockRLM, true);
closeLocalInstance();
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
closeLocalInstance();
}
});
}
}
它会工作,除了那些写的方法不能在后台线程上执行 - 只能在 ui 线程上执行 - 所以我会添加类似下面的方法
private void executeInTransaction(Realm.Transaction transaction) {
try {
Realm realm = openLocalInstance();
if(!realm.isAutoRefresh()) {
try {
boolean wasInTransaction = realm.isInTransaction();
if(!wasInTransaction) {
realm.beginTransaction();
}
transaction.execute(realm);
if(!wasInTransaction) {
realm.commitTransaction();
}
} catch(Throwable e) {
if(realm.isInTransaction()) {
realm.cancelTransaction();
}
}
} else {
realm.executeTransactionAsync(transaction);
}
} finally {
closeLocalInstance();
}
}
通过这种方式,您可以通过手动打开事务进行批量后台操作 + 从 UI 线程执行异步写入。
您需要进行一些调整才能添加 "success/failure" 侦听器,但基础知识已具备。