Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

Android设计模式:单例模式

by
Difficulty:BeginnerLength:ShortLanguages:

Chinese (Simplified) (中文(简体)) translation by Zhang Xiang Liang (you can also view the original English article)

什么是单例模式?

单例模式(Singleton Pattern)是一种软件设计模式,它可以保证一个类只有一个实例,并且该类提供了全局访问。  每当多个类或客户端请求该类时,都将获得该类的相同实例。该Singleton类可以实例化自己,也可以通过工厂类获得对象。

我们来看一下手机及其拥有者的例子。手机通常由一个人拥有,而一个人可以拥有许多手机。这些手机中任何一个响起铃声,同一位拥有者就会接电话。

单例模式的好处

在一个典型的Android APP中,我们只需要对象的一个全局实例,无论是直接使用它还是简单地将它传递给另一个类。这样的例子很多,包括高速缓存,  OkHttpClient,  HttpLoggingInterceptor,  Retrofit,  Gson,  SharedPreferences和仓库类等。 如果我们把这些类实例化了多个对象,我们就会遇到许多问题,比如异常的APP反应,资源过度使用和其他混乱的结果。

实现

实现这种模式很容易。以下代码片段显示了如何创建Singleton。

在上面的代码中,我们有一个静态变量INSTANCE来保存类的一个实例。我们还将构造函数设为私有,因为我们要强制不可修改 - 类只能实例化。  getInstance()方法保证该类被实例化,如果没有被实例化,就新建一个。

示例:创建Retrofit单例

Retrofit是通过将API转换为Java接口来连接REST Web服务的流行库。要了解更多信息,请查看我在Envato Tuts +上的教程。

在Android APP中,你需要一个全局的Retrofit实例对象,以便APP的其他部分(如UserProfileActivitySettingsActivity)可以使用它来执行网络请求,而无需在每次需要时创建一个实例。 创建多个实例会污染我们的APP,多个无用的retrofit对象会占用移动设备上的不必要的内存,而内存本来就很紧张。

所以在客户端A调用RetrofitClient.getClient()的时候,如果对象尚未创建实例,则创建该实例,然后当客户端B调用此方法时,它会检查“Retrofit”实例是否已存在。如果实例已存在,它将实例返回给客户端B,而不是创建一个新的实例。

处理多线程

在Android系统中,你可以分离多个线程来执行不同的任务。这些线程可以同时执行相同的代码块。 在上述Singleton类的情况下,这可能导致创建多个实例对象,这违反了Singleton原则。 所以我们的Singleton代码片段中的getInstance()方法不是线程安全的。我们现在来看看如何使线程安全。

同步getInstance()方法 

使单例代码线程安全的方法之一是使getInstance()方法成为同步方法。这样做只允许一个线程一次运行该方法,强制每个其他线程处于等待或阻塞状态。

这种方法使我们的代码线程安全,但这是一个昂贵的操作。换句话说,这可能会降低性能。所以你必须检查并看看你的APP性能成本是否值得这样做。

热切地创建一个实例

让多线程安全的另一种方法是在加载或初始化类(由 Dalvik VM中的Android ClassLoader)时立即创建Singleton实例。 这使得代码线程安全。然后在任何线程访问INSTANCE变量之前,对象实例已经可用。 

这种方法的一个缺点是,你可能创建了一个永远不会使用的对象,从而占用不必要的内存。所以这个方法通常只有在你确定单例被访问时才可以使用。

Bonus:使用Dagger2

依赖注入库(如Dagger)可以帮助你连接对象依赖关系,并通过使用@Singleton注解来创建单例。这将确保对象仅在整个应用程序生命周期中初始化一次。

在上面的代码中,我们创建了GsonCacheFile,  OkHttpClientRetrofit的单例。 

想学习有关Dagger 2的更多信息,请参阅我们在Envato Tuts +上的教程。 

结语

在这篇简短的教程中,你学到了Android中的单例模式,包括:它是什么,使用它的好处,如何通过编写自己的方法来实现它,以及处理多个线程的一些方法。我还向你展示了如何使用第三方库,如Dagger 2。 

与此同时,请查看关于Java语言和Android APP开发的其他教程!

关注我们的公众号
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.