简体   繁体   English

Android上基于枚举的单例的生命周期

[英]Lifecycle of enum based singleton on Android

A few days ago I've discovered that singleton can become anti-pattern in Android. 几天前,我发现单身人士可以在Android中成为反模式。 My singleton (class with private constructor and instance stored in static field) was deleted (instance was deleted despite the fact other activities were still using this singleton (via getInstance() method) so another instance had to be created ) because Activity from which it was first invoked was deleted (after invoking finish for only this one activity). 我的单例(具有私有构造函数的类和存储在静态字段中的实例)被删除(尽管其他活动仍在使用此单例(通过getInstance()方法),因此实例已被删除,因此必须创建另一个实例)因为Activity从中第一次调用被删除(在仅为此一项活动调用完成后)。

I've read already how this problem can be resolved however I've also just read "Effective Java". 我已经读过这个问题是如何解决的,但是我也读过“Effective Java”。 There is said that "Single-element enum type is the bast way to implement a singleton". 据说“单元素枚举类型是实现单例的麻烦方式”。

So now I'm wondering what would be the lifecycle of singleton created this way in Android application? 所以现在我想知道在Android应用程序中以这种方式创建的单例的生命周期是什么? Would it be the same like in case of "standard singleton implementation" so after destroying activity from which it was invoked the first time it will be destroyed (even if it used also in other activities)? 它是否与“标准单例实现”的情况相同,因此在破坏第一次被销毁时调用它的活动(即使它也用于其他活动)?

I'm not asking about proper android singleton implemenation or the singleton pattern itself (is it pattern or anti-pattern etc) but I'd like to know what be the lifecycle of such enum singleton object and when it will be destroyed. 我不是要问关于正确的android单例实现还是单例模式本身(是模式还是反模式等),但是我想知道这个枚举单例对象的生命周期是什么以及什么时候它会被销毁。

In all cases, the classes you use are tied to the ClassLoader that loaded them. 在所有情况下,您使用的类都与加载它们的ClassLoader相关联。 This is true in Java in general, not just Android. 这在Java中通常都是如此,而不仅仅是Android。 Android will isolate activities by using new ClassLoader s each time -- at the least, it doesn't promise it won't, and it does as far as I can tell. Android将通过每次使用新的ClassLoader来隔离活动 - 至少,它不承诺它不会,并且它尽我所知。

Any singleton, or other class-level state, is tied to the Class which is tied to the ClassLoader . 任何单例或其他类级别状态都与绑定到ClassLoaderClass相关联。 This is why your state "disappears"; 这就是你的国家“消失”的原因; it's actually that your calling code is seeing a new Class in a new ClassLoader . 它实际上是调用代码是看到一个新的Class在一个新的ClassLoader

So, your enum-based trick, or anything else along these lines, would have exactly the same behavior. 因此,基于枚举的技巧或这些行中的任何其他技巧都会产生完全相同的行为。 You just can't "persist" activity information this way. 你不能以这种方式“持久”活动信息。 You can and should write to a SQLite DB. 您可以而且应该写入SQLite DB。 You could probably stash it in the SharedPreferences too. 您也可以将它存储在SharedPreferences

The application object is a good location to store information which needs to be accessible to various activity or service instances. 应用程序对象是存储需要可供各种活动或服务实例访问的信息的良好位置。 You can retrieve it like this (where this is an Activity or Service): 您可以像这样检索它(这是一个活动或服务):

private MyApplication app; 私人MyApplication应用;

in onCreate(...){ ... this.app = (MyApplication) this.getApplication(); in onCreate(...){... this.app =(MyApplication)this.getApplication(); ... } ...}

Remember to set the name also in the manifest: Set the attribute "name" of the "application" tag: The value is the path to the class relative to the package of your app. 请记住在清单中也设置名称:设置“application”标记的属性“name”:值是相对于应用程序包的类的路径。

The application object is created when the app is started, you can initialize like in an activity or service in it's onCreate() method. 应用程序启动时创建应用程序对象,您可以在其onCreate()方法中的活动或服务中初始化。

One thing to remember: The application object can survive closing your "last" activity. 要记住的一件事是:应用程序对象可以在关闭“最后”活动后继续存在。 In this case you may get the same application object with the state from the previous interaction with your app. 在这种情况下,您可以使用之前与应用程序交互的状态获取相同的应用程序对象。 If this is a problem you must somehow detect the initial start of your app (eg using a special launcher activity without UI, which initializes the application object and then starts a new intent. BTW, the same may happen with singletons if they have not yet been lost to garbage collection. 如果这是一个问题,你必须以某种方式检测你的应用程序的初始启动(例如,使用一个没有UI的特殊启动器活动,初始化应用程序对象,然后启动一个新的意图。顺便说一下,如果他们还没有单身人士可能会发生同样的情况丢了垃圾收集。

My secure singleton implementation is like that: 我的安全单例实现是这样的:

I create a singleton class which has an attribute of boolean 'didReceiveMemoryWarning'; 我创建了一个单例类,其属性为boolean'doveReceiveMemoryWarning';

public class SingleTon(){
     public boolean didReceiveMemoryWarning = true;
     ...
     ...
}

In application first screen(It is exactly first launch screen)(I have a splash screen that is visible 3 sec) 在应用程序第一个屏幕(它正是第一个启动屏幕)(我有一个可见的闪屏3秒)

SingleTon.getInstance().didReceiveMemoryWarning = false;

And in every Activity's onCreate() method, check this boolean data, 在每个Activity的onCreate()方法中,检查这个布尔数据,

@Override
public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);

     if(SingleTon.getInstance().didReceiveMemoryWarning){
          { Load your data from local to your SingleTon class, 
             because your app was released by OS};
     }
}

it is my implementation. 这是我的实施。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM