Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android中的单例与应用程序上下文?_Java_Android_Design Patterns_Singleton - Fatal编程技术网

Java Android中的单例与应用程序上下文?

Java Android中的单例与应用程序上下文?,java,android,design-patterns,singleton,Java,Android,Design Patterns,Singleton,回顾这一点 看过几个使用singleton模式的Android应用程序示例后,我想知道使用singleton而不是通过全局应用程序状态共享的单个实例(将Android.os.application子类化并通过context.getApplication()获取它)是否是个好主意 两种机制都有哪些优点/缺点 老实说,我希望在这篇文章中得到同样的答案,但适用于Android。我说得对吗?DalvikVM有什么不同 编辑:我想就涉及的几个方面发表意见: 同步 可重用性 测试 它们实际上是一样的。 我

回顾这一点 看过几个使用singleton模式的Android应用程序示例后,我想知道使用singleton而不是通过全局应用程序状态共享的单个实例(将Android.os.application子类化并通过context.getApplication()获取它)是否是个好主意

两种机制都有哪些优点/缺点

老实说,我希望在这篇文章中得到同样的答案,但适用于Android。我说得对吗?DalvikVM有什么不同

编辑:我想就涉及的几个方面发表意见:

  • 同步
  • 可重用性
  • 测试
它们实际上是一样的。
我可以看出有一点不同。使用Application类,您可以在Application.onCreate()中初始化变量,并在Application.onTerminate()中销毁它们。对于singleton,您必须依赖VM初始化和销毁静态。

我非常推荐singleton。如果您有需要上下文的单例,请:

MySingleton.getInstance(Context c) {
    //
    // ... needing to create ...
    sInstance = new MySingleton(c.getApplicationContext());
}
我更喜欢单例而不是应用程序,因为它有助于使应用程序更具组织性和模块化,而不是在一个地方维护整个应用程序的所有全局状态,每个单独的部分都可以自行处理。还有一个事实,即Singleton(在请求时)延迟初始化,而不是引导您在Application.onCreate()中提前完成所有初始化,这是很好的

使用单例没有本质上的错误。只要在有意义的时候正确地使用它们。Android框架实际上有很多这样的功能,它可以维护每个进程的已加载资源缓存以及其他类似的功能

对于简单的应用程序,多线程不会成为单例的问题,因为通过设计,对应用程序的所有标准回调都在进程的主线程上调度,所以除非通过线程显式引入多线程,或者通过向其他进程发布内容提供商或服务IBinder隐式引入多线程,否则不会发生多线程


只是想一想你在做什么。:)

我也有同样的问题:Singleton还是生成一个子类android.os.Application

首先,我尝试使用Singleton,但我的应用程序在某个时候会调用浏览器

Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
问题是,如果手机没有足够的内存,你的大多数类(甚至是单件)都会被清理以获得一些内存,因此,当从浏览器返回到我的应用程序时,它每次都会崩溃


解决方案:将所需数据放入应用程序类的子类中。

我非常不同意Dianne Hackborn的回答。我们正在一点一点地从我们的项目中删除所有的单例,以支持轻量级、任务范围的对象,这些对象可以在您实际需要时轻松地重新创建

单例是测试的噩梦,如果延迟初始化,将引入带有细微副作用的“状态不确定性”(在将对
getInstance()
的调用从一个作用域移动到另一个作用域时,可能会突然出现这种副作用)。可见性被提到是另一个问题,由于单例意味着对共享状态的访问是“全局的”(=random),因此如果在并发应用程序中没有正确同步,可能会出现细微的错误

我认为它是一种反模式,它是一种糟糕的面向对象风格,本质上是维护全局状态。

回到你的问题上来:


尽管应用程序上下文本身可以被视为一个单例,但它是框架管理的,并且具有定义良好的生命周期、范围和访问路径。因此,我认为,如果您确实需要管理应用程序全局状态,它应该放在这里,而不是其他地方。对于其他任何事情,请重新考虑是否确实需要单例对象,或者是否也可以重写单例类来实例化执行手头任务的小型、短期对象。

同时考虑这两个问题:

  • 将单例对象作为类内的静态实例
  • 具有一个公共类(上下文),该类返回应用程序中所有singleton对象的单例实例,其优点是上下文中的方法名称将是有意义的,例如:Context.getLoggedinUser()而不是User.getInstance()
此外,我建议您扩展您的上下文,不仅包括对单例对象的访问,还包括一些需要全局访问的功能,例如:Context.logOffUser()、Context.readSavedData()等。那么,将上下文重命名为Facade可能有意义。

来源:

通常不需要对应用程序进行子类化。在大多数情况下, 静态单例可以以更模块化的方式提供相同的功能 对。如果您的单身汉需要全局上下文(例如注册 广播接收器),检索它的函数可以给定 上下文,当 首先构造单例


我的活动调用finish()(虽然不会立即完成,但最终会完成),并调用Google Street Viewer。当我在Eclipse上调试它时,调用Street Viewer时,我与应用程序的连接中断,我理解为(整个)应用程序被关闭,应该是为了释放内存(因为完成的单个活动不应该导致这种行为)。尽管如此,我仍然能够通过onSaveInstanceState()将状态保存在Bundle中,并在堆栈中下一个活动的onCreate()方法中将其还原。无论是使用静态单例还是子类化应用程序,我都会面临应用程序关闭和丢失的状态(除非我将其保存在捆绑包中)。因此,根据我的经验,它们在国家保护方面是相同的。我注意到Android 4.1.2和4.2.2中的连接丢失,但在4.0.7或3.2.4中没有,据我所知,这表明内存恢复机制在某个时候发生了变化
public class AndroidApplication extends Application {

    private static AndroidApplication sInstance;

    public static AndroidApplication getInstance(){
        return sInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sInstance = this;
    }
}