我是Realm(和Android开发)的新手,我想使用Singleton类来简化Realm数据管理,这样我的朋友就可以更轻松地在我们的小组项目中使用。
EpicPandaForce编写了一个名为RealmManager here的单例类,但我找不到实现它的例子,所以这就是我尝试过的:
public class RealmManager {
private static RealmManager instance;
private final ThreadLocal<Realm> localRealm = new ThreadLocal<>();
RealmManager(){}
public synchronized static RealmManager getInstance(){
if(instance == null){
instance = new RealmManager();
}
return instance;
}
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);
}
}
public void storePreferenceDao(int userID, String rank){
final PreferenceDao preferenceDao = new PreferenceDao();
preferenceDao.setUserID(userID);
preferenceDao.setRank(rank);
openLocalInstance();
getLocalInstance().executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(preferenceDao);
}
}, new Realm.Transaction.OnSuccess(){
@Override
public void onSuccess(){
System.out.println("Data is stored successfully!");
}
}, new Realm.Transaction.OnError(){
@Override
public void onError(Throwable error){
System.out.println("There is an error in storePreferenceDao()");
}
});
closeLocalInstance();
}
因此,当我的朋友想要存储一些数据时,他们可以使用:
RealmManager.getInstance().storePreferenceDao(123, "Alpaca");
这是应该如何使用它还是多余的?我怎样才能提高效率呢?
答案 0 :(得分:0)
一个简单的Singleton示例,
public class MySingleton {
private static MySingleton sMySingleton;
//private constructor.
private MySingleton() {
if (sMySingleton != null){
throw new RuntimeException("Use getInstance() for the instance");
}
}
public synchronized static MySingleton getInstance() {
if (sMySingleton == null){
sMySingleton = new MySingleton();
}
return sMySingleton;
}
}
希望它有所帮助!
答案 1 :(得分:0)
这可能不是最好的答案,但在这里我如何在我的应用程序中使用领域
public class BaseActivity extends AppCompatActivity {
public Realm realm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
realm = Realm.getDefaultInstance();
}
}
根据您的使用在其他活动中扩展BaseActivity
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Here you can directly access realm object and perform your task
realm.where()//just example
}
@Override
protected void onDestroy() {
super.onDestroy();
if(realm!=null)
realm.close();
//Don't forget to close realm object
}
}
我不是说这是最好的方式,但它是最好的方式。使用这种方式,我可以轻松管理我的领域类,并可以减少与realm相关的错误。对于片段你可以制作BaseFragment并将其扩展到其他片段。
希望这会对你有所帮助......如果你有更好的方法,请告诉我
答案 2 :(得分:0)
实际上在这种情况下,仍然只能从UI线程调用该方法,并且应该在事务回调中关闭本地实例(否则不会调用onSuccess / onError)
如果能够,你可以创建一个能够在bg线程上执行的方法,如果已经在bg线程上,你可以在当前线程上执行
// method in RealmManager
public final void runTransaction(Realm.Transaction transaction) {
runTransaction(transaction, null, null);
}
public final void runTransaction(Realm.Transaction transaction, Realm.Transaction.OnSuccess onSuccess) {
runTransaction(transaction, onSuccess, null);
}
public final void runTransaction(Realm.Transaction transaction, Realm.Transaction.OnSuccess onSuccess, Realm.Transaction.OnError onError) {
Realm realm = openLocalInstance();
if(realm.isAutoRefresh()) {
realm.executeTransactionAsync(transaction, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
try {
if(onSuccess != null) {
onSuccess.onSuccess();
}
} finally {
closeLocalInstance();
}
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable e) {
try {
if(onError != null) {
onError.onError(e);
}
} finally {
closeLocalInstance();
}
}
});
} else {
try {
realm.executeTransaction(transaction);
if(onSuccess != null) {
onSuccess.onSuccess();
}
} catch(Exception e) {
if(onError != null) {
onError.onError(e);
}
throw new RuntimeException(e);
} finally {
closeLocalInstance();
}
}
}
如果添加此方法,那么现在可以执行一个事务,如果可能的话,将通过async
事务方法在后台线程上执行,如果不是在looper线程上,则使用synchronous
事务方法( f.ex.background thread)
这样你就可以了
public void storePreferenceDao(int userID, String rank) {
final PreferenceDao preferenceDao = new PreferenceDao();
preferenceDao.setUserID(userID);
preferenceDao.setRank(rank);
runTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(preferenceDao);
}
}, new Realm.Transaction.OnSuccess(){
@Override
public void onSuccess(){
System.out.println("Data is stored successfully!");
}
}, new Realm.Transaction.OnError(){
@Override
public void onError(Throwable error){
System.out.println("There is an error in storePreferenceDao()");
}
});
}
或者只是
public void storePreferenceDao(int userID, String rank) {
final PreferenceDao preferenceDao = new PreferenceDao();
preferenceDao.setUserID(userID);
preferenceDao.setRank(rank);
runInTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(preferenceDao);
}
});
}
你知道,我一直觉得我应该为这个例子添加一个runTransaction()
方法。但是,如果能够与否,默认情况下默认使用executeTransactionAsync
是否值得辩论。