我正在使用领域和碎片的应用程序。领域设置需要加密,并且要删除领域db,并在用户注销时生成新密钥。可靠地关闭领域(片段)
为了执行注销操作,我在没有任何碎片的任务顶部启动一项新的活动,并启动一个处理所有注销清理的IntentService。
我遇到的问题是,我似乎无法可靠地让我的碎片放开他们的领域实例,让领域被删除。在onStop/onPause/onDestroy中关闭片段领域时,总会有一两个片段似乎需要花时间从Android的片段缓存中关闭/清除。
我已将我的视图传呼机切换到使用FragmentStatePagerAdapers,这减少了打开的片段数量,并有所帮助。
因此,在我的IntentService中,我采取了循环Realm.delete(),直到它成功 - 它最终似乎做到了。有时等待时间很短,有时是几分钟。这是非常可变的。
我以前想过的事情是用事件触发事件(使用EventBus),这些片段监听这些事件会导致它们关闭它们的领域实例。
但有没有更好的方式让我的碎片关闭/及时关闭他们的领域实例(除了不使用碎片)?
RealmFragment.java:
import android.support.v4.app.Fragment;
import android.util.Log;
import io.realm.Realm;
public class RealmFragment extends Fragment {
private Realm realm = null;
private final Object realmLock = new Object();
public Realm getRealm() {
if (realm == null || realm.isClosed()) {
synchronized (realmLock) {
if (realm == null || realm.isClosed()) {
realm = Realm.getDefaultInstance();
}
}
}
return realm;
}
@Override
public void onPause() {
super.onPause();
closeRealm();
}
@Override
public void onStop() {
super.onStop();
closeRealm();
}
@Override
public void onDestroy() {
super.onDestroy();
closeRealm();
}
private void closeRealm() {
if (realm != null && !realm.isClosed()) {
synchronized (realmLock) {
if (realm != null && !realm.isClosed()) {
try {
realm.close();
}
catch (Exception e) {
Log.e("REALM","Couldn't close realm.");
}
realm = null;
}
}
}
}
}
登录屏幕启动:
case R.id.logout: {
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle(R.string.confirm_sign_out)
.setMessage(R.string.sign_out_description)
.setPositiveButton(
android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// close this activity's realm before launching sign out.
MyActivity.closeRealm();
Intent signOutIntent = new Intent(MyActivity.this, SignOutActivity.class);
signOutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
// this starts the logout process. It begins with removing an Android
// system account, and a receiver that listens for that to complete. When
// the account removal is complete, then we can continue with the rest of
// the logout process.
Actions.logoutAccount(getApplicationContext());
startActivity(signOutIntent);
// I could call this before calling startActivity()?
MyActivity.finish();
}
})
.setNegativeButton(
android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setCancelable(true)
.create();
alertDialog.show();
break;
}
我个人建议在保留片段的构造函数或onCreate()中打开一个Realm实例,然后将该片段绑定到您的Activity并关闭onDestroy()中的领域。这样,只会有一个共享Realm,并且它将被绑定到没有缓存的活动生命周期。你会从该保留的片段中将该Realm引用到你的Activity中,而你的其他片段将从Activity中获得它们的Realm引用。 – EpicPandaForce
片段生命周期是非常困难的。你有没有试过寻找http://developer.android.com/reference/android/app/Fragment.html#setUserVisibleHint(boolean)或haps控制你的任务堆栈,所以你打开你的登录/注销时强制关闭所有活动屏幕? –
@EpicPandaForce - 领域实例是懒惰地获取的,而不是onCreate() - 我有太多问题,实例变得无效。我将添加上面使用的代码。 – Mark