回顾这篇文章,列举了使用单例对象的几个问题
并且已经看到了几个使用单例模式的Android应用程序的例子,我想知道使用单例而不是通过全局应用程序状态共享的单个实例是否是一个好主意(子类化Android .os. application并通过context.getApplication()获取它)。
这两种机制有什么优点/缺点?
老实说,我希望在这篇文章中得到同样的答案,单例模式与Web应用程序,不是一个好主意!但应用于Android。我说的对吗?DalvikVM有什么不同?
编辑:我想就所涉及的几个方面发表意见:
同步
可重用性
测试
我强烈推荐单身人士。如果你有一个需要context的单例,有:
MySingleton.getInstance(Context c) {
//
// ... needing to create ...
sInstance = new MySingleton(c.getApplicationContext());
}
比起应用程序,我更喜欢单例,因为它有助于保持应用程序更有组织性和模块化——而不是在一个地方维护整个应用程序的所有全局状态,每个单独的部分都可以照顾自己。另外,单例会延迟初始化(在请求时),而不是引导您在Application.onCreate()中预先进行所有初始化,这是很好的。
使用单例对象在本质上并没有错。只要在有意义的时候正确地使用它们。Android框架实际上有很多,用于维护加载资源的每个进程缓存和其他类似的东西。
同样,对于简单的应用程序,多线程不会成为单例的问题,因为根据设计,所有对应用程序的标准回调都在进程的主线程上分派,所以你不会发生多线程,除非你通过线程显式地引入它,或者通过将内容提供程序或服务IBinder隐式地发布给其他进程。
对你所做的事情要深思熟虑。:)
我也有同样的问题:单例还是做一个子类android.os.Application?
首先,我尝试了单例,但我的应用程序在某些时候会调用浏览器
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
问题是,如果手机没有足够的内存,你的大多数类(甚至是单例)被清理以获得一些内存,当从浏览器返回到我的应用程序时,它每次都崩溃了。
解决方案:将需要的数据放在Application类的子类中。
我非常不同意Dianne Hackborn的回答。我们一点一点地从我们的项目中移除所有的单例对象,以支持轻量级的、任务范围的对象,当你真正需要它们时,它们可以很容易地重新创建。
单例是测试的噩梦,如果延迟初始化,将引入带有微妙副作用的“状态不确定性”(当将对getInstance()的调用从一个作用域移动到另一个作用域时,可能会突然出现)。可见性是另一个问题,由于单例意味着对共享状态的“全局”(=随机)访问,在并发应用程序中没有正确同步时,可能会出现微妙的错误。
我认为这是一种反模式,它是一种糟糕的面向对象风格,本质上相当于维护全局状态。
回到你的问题:
虽然应用程序上下文本身可以被认为是一个单例,但它是由框架管理的,并且具有定义良好的生命周期、作用域和访问路径。因此,我认为如果你确实需要管理app-global状态,它应该放在这里,而不是其他地方。对于其他任何事情,重新考虑是否真的需要一个单例对象,或者是否也可以重写单例类来实例化执行手头任务的小型、短期对象。
My activity calls finish() (which doesn't make it finish immediately, but will do eventually) and calls Google Street Viewer. When I debug it on Eclipse, my connection to the app breaks when Street Viewer is called, which I understand as the (whole) application being closed, supposedly to free up memory (as a single activity being finished shouldn't cause this behavior). Nevertheless, I'm able to save state in a Bundle via onSaveInstanceState() and restore it in the onCreate() method of the next activity in the stack. Either by using a static singleton or subclassing Application I face the application closing and losing state (unless I save it in a Bundle). So from my experience they are the same with regards to state preservation. I noticed that the connection is lost in Android 4.1.2 and 4.2.2 but not on 4.0.7 or 3.2.4, which in my understanding suggests that the memory recovery mechanism has changed at some point.
从众所周知的马的嘴…
在开发你的应用程序时,你可能会发现有必要在整个应用程序中共享数据、上下文或服务。例如,如果你的应用程序有会话数据,比如当前登录的用户,你可能会想要公开这些信息。在Android中,解决这个问题的模式是让你的Android .app.Application实例拥有所有的全局数据,然后把你的Application实例当作一个具有各种数据和服务的静态访问器的单例。
当编写一个Android应用程序时,你保证只有一个Android .app. application类的实例,所以它是安全的(谷歌Android团队推荐)将其视为单例。也就是说,您可以安全地将静态getInstance()方法添加到应用程序实现中。像这样:
public class AndroidApplication extends Application {
private static AndroidApplication sInstance;
public static AndroidApplication getInstance(){
return sInstance;
}
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
}
}