我在 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和文件描述符,因此关闭您的领域实例很重要。
。有关更多信息,请访问此链接。