我正在使用領域和碎片的應用程序。領域設置需要加密,並且要刪除領域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