如果我在不关闭开放式领域实例的情况下关闭Android应用程序会发生什么



我在 Application类中的主线程上打开了一个领域实例,我使用该实例从MainActivity进行各种DB操作。由于我的应用程序有一个活动,因此我关闭了活动的onDestroy()中的实例。该应用程序到目前为止对我来说很好。

不做realm.close()的影响是什么?我的数据库并未在没有相同的情况下损坏。

另外,我已经读到,在某些情况下,活动的onDestroy()可能根本不会被调用。如果关闭领域如此重要,那么在这种情况下,数据库会产生什么影响?

public class MyApp extends Application {
    private static MyApp instance;
    private Realm realm;
    public void onCreate() {
        super.onCreate();
        Realm.init(this);
        Realm.setDefaultConfiguration(new RealmConfiguration.Builder()
                .schemaVersion(BuildConfig.VERSION_CODE)
                .migration(new RealmMigrationClass())
                .compactOnLaunch()
                .build());
        realm = Realm.getInstance(Realm.getDefaultConfiguration());
    }
    public static MyApp getInstance() {
        return instance;
    }
    public Realm getRealm() {
        return realm;
    }
}

MainActivity

public class MainActivity extends Activity {
    @Override
    protected void onDestroy() {
        MyApp.getInstance().getRealm().close();
        super.onDestroy();
    }
}

关闭领域的实例非常重要,因为领域核心已经用C 编程语言编写,并在本机代码中编译。我们知道C 垃圾集合确实不自动运行,我们需要手动调用垃圾收集。job.from realm.close((表示您给命令或告诉本机C 编译器以运行垃圾收集。

如果您查找java领域的" doc"(ronem_doc(,您可以找到:

领域实施可靠近的人来照顾本地记忆差距 和文件描述符,因此始终关闭您的领域实例 与他们一起完成。

领域实例是参考计数的 - 如果您两次致电Getinstance 线程,您也需要致电两次。这使您可以 实现可运行的类,而不必担心哪个线程 将执行它们:只需使用getinstance开始并以此结束 关闭。

我个人建议您定义一个类别定义领域函数和"领域属性"(例如" Realmhelper"类(的类,然后在此类中定义: - 一个不变的领域 - 静态领域实例

您将始终使用此领域静态实例,用于主线程内部的所有操作,在其他线程内您将在执行操作之后称为" new Realmhelper(("并关闭领域。

>

在关闭应用程序关闭时,您只需要关闭一个领域实例,您可以在自定义定义的应用程序类中使用" Application.activity.activity.activityLifecyClecallbacks"接口(因此扩展了Android的应用程序(。

示例您的应用程序自定义类:

/* START Override ActivityLifecycleCallbacks Methods */
    @Override
    public void onActivityCreated(Activity activity, Bundle bundle) {
    }
    @Override
    public void onActivityStarted(Activity activity) {
        // Check if your MyRealmClass instance is null or is closed, in this case 
        // re-initialize it.
        if(MyRealmClass.getInstance() == null || MyRealmClass.getInstance().getRealm().isClosed()){
            MyRealmClass.initInstance();
        }
    }
    @Override
    public void onActivityResumed(Activity activity) {
    }
    @Override
    public void onActivityPaused(Activity activity) {
    }
    @Override
    public void onActivityStopped(Activity activity) {
        if(!AppUtils.isAppOnForeground(this)){
            // Close your MyRealmClass instance
            if(MyRealmClass.getInstance() != null) {
                MyRealmClass.getInstance().close();
             MyRealmClass.getInstance().logRealmInstanceCount(LABEL_APP_IN_BACKGROUND);
                MyRealmClass.setMyInstance(null);
            }
        }
    }
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
    }
    @Override
    public void onActivityDestroyed(Activity activity) {
    }
    /* END Override ActivityLifecycleCallbacks Methods */

" iSapponForeground"的代码(检查您的应用程序是否在前景中,如果不是这意味着您的应用程序已关闭(:

public static boolean isAppOnForeground(Context context) {
        boolean ret = false;
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if(appProcesses != null){
            String packageName = context.getPackageName();
            for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
                    ret = true;
                }
            }
        }
        return ret;
    }

您的" Myrealmclass"看起来像:

public class MyRealmClass {
 protected Realm mRealm;
    protected static MyRealmClass mInstance;
    public MyRealmClass() {
        mRealm = Realm.getDefaultInstance();
    }
    public static MyRealmClass initInstance(){
        if(mInstance == null){
            mInstance = new MyRealmClass();
        }
        return mInstance;
    }
public static MyRealmClass getInstance(){
        return mInstance;
    }
public static void setMyInstance(MyRealmClass instance) {
        mInstance = instance;
    }
public Realm getRealm() {
        return mRealm;
    }
    public void setRealm(Realm realm){
        this.mRealm = realm;
    }
public void close() {
        if (mRealm != null) {
            try {
                mRealm.close();
            } catch(Exception e){
                onException(e);
            }
        }
    }
[...]

然后,您需要检查当使用RealMobject或在领域中执行某些操作时,您需要检查所有领域实例是否均未关闭。而且,如果它关闭(因为该应用程序在后台,然后重新启动(,则需要重新启动该领域(如果您的活动具有Myrealmclass实例为属性(。示例性示例:

public abstract class MyBaseActivity extends AppCompatActivity {
    protected MyRealmClass mRealmClass;
    /* START Override Lifecycle Methods */
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initMyRealmClass();
        Lyra.instance().restoreState(this, savedInstanceState);
    }
    @Override
    protected void onStart() {
        super.onStart();
        initMyRealmClass();
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Lyra.instance().saveState(this, outState);
    }
    /* END Override Lifecycle Methods */
    /* START Private Methods */
    protected void initMyRealmClass(){
        if(mRealmClass == null || mRealmClass.getRealm().isClosed()){
            mRealmClass = MyRealmClass.initInstance();
        }
    }
    /* END Private Methods */
}

基本上,如果您需要使用领域功能,那么您所有的活动都将扩展这种基础性。(Lyra用于保存您的任何属性的状态:lyra(

记住:

如果您从RealMobject设置或获取一些属性,或者您从realmlist或Realmresults获得对象,则需要将对象所取用的领域实例打开。否则,当您在域中使用对象的变量启动变量时,需要使用此方法:

public <T extends RealmObject> List<T> toList(RealmResults<T> results) {
            return mRealm.copyFromRealm(results);
        }
        public <T extends RealmObject> List<T> toList(RealmList<T> results) {
            return mRealm.copyFromRealm(results);
        }
        public <T extends RealmObject> T copyObjectFromRealm(T obj) {
            return mRealm.copyFromRealm(obj);
        }
    public <T extends RealmObject> RealmResults<T> findAllObject(Class<T> classObject) {
        RealmQuery<T> query = mRealm.where(classObject);
        return query.findAll();
    }

现在,如果您需要获取" MyrealMobjectClass"对象的列表并将它们添加到适配器中,则将执行此操作:

List<MyRealmObjectClass> myObjects = mRealmClass.toList(mRealmClass.findAllObject(MyRealmObjectClass.class))
myAdapter.addAll(myObjects);

如果您"获取"或"设置"领域实例之后的属性,从中获得对象已关闭(例如,在应用程序进入后台并重新启动后(,您将不会得到例外。但是,如果您"设置"了领域的属性,则不会在领域实例中设置该属性,因此在这种情况下,要更改领域内的RealMobject的值,您需要保存对象!否则,如果您有一个仍然连接到领域的领域或RealMobject,则可以在交易中直接更改其属性,并且它将在领域内更改。要进行领域的交易,我建议您在第一个链接中关注DOC,如果您不需要关闭最终块中的领域,请启用Lambda并执行此操作:

mRealm.executeTransaction(
    realm -> {
        [do your Realm operations]
    }
)

也可以做:

public boolean doRealmOperation(Object... params){
AtomicBoolean ret = new AtomicBoolean(false);
mRealm.executeTransaction(
    realm -> {
        try{
            [do your realm operation]
            ret.set(true);
        } catch(Exception e){
           onException(e)
           ret.set(false);
        }
    }
)
}

在这种情况下,您需要使用" atomicboolean"(必须是最终变量。但是您不能将" ret"定义为"最终",然后再次设置它,因此您需要使用" atomicboolean"将交易之外的变量设置为设置,并将其再次设置在交易本身内。(您还可以通过使用临时变量来避免此问题,以在交易中获取" true/false"值,然后使用该" temp变量"设置" ret"变量。但是我个人更喜欢使用" atomicboolean"类,我认为,比温度变量更安全,更干净(

希望这有帮助,与您见面并愉快的编码!;(

领域可实现可闭合以照顾本地内存互换和文件描述符,因此,始终关闭您的领域实例。

领域实例是参考计数的 - 如果您在线程中两次致电Getinstance,则需要两次关闭。

根据我的个人经验,没有关闭领域并没有引起很多问题,实际上,当我有时尝试关闭它时,当应用程序进入后台并恢复时,会导致问题实例已关闭,我不确定为什么在这种情况下未创建一个新的领域实例,可能是一个错误。

到目前为止,我关注领域文档并关闭我的领域实例,直到它们引起问题为止。

一般的编码实践表明,打开的任何东西都应安全地关闭。

是的,只有在您称为关闭时,它才会关闭((您应用程序的方法 destion((方法。请记住领域实现可关闭的,以照顾本机内存Deallocation和文件描述符,因此关闭您的领域实例很重要。

有关更多信息,请访问此链接。

最新更新