单例模式在android中使用

单例模式(Singleton)

单例模式是对象的创建模式,单例模式能够确保某个类只有一个单一的实例对象存在,同时能够自行实例化并将单一的实例提供给外界调用的特点,其在实际项目开发中经常被用到。

单例模式的结构图说明如下:

结合上面的模式结构说明图,我们可以看到单例模式有几个显著的特点,具体如下所示:

A、单例类(Singleton)只能有一个唯一的实例存在。

B、单例类必须有能够自行创建自己的实例对象的能力。

C、单例类必须能够给外界其他对象提供这个实例。

另外,对于单例模式从产生到现在,也已经有了几种形式,下面我们就介绍几种常用到的形式(以代码的形式说明):

第一种形式:

/*

 * 单例模式---形式1

 */

public class SingletonA {

     private static final SingletonA instance = new SingletonA();

    

     /* 私有构造子*/

     private SingletonA() {

          // CODE

     }

    

     /* 供外部调用的实例方法*/

     public static SingletonA getInstance(){

          return instance;

     }

}

第二种形式:

/*

 * 单例模式---形式2

 */

public class SingletonB {

     private static SingletonB instance = null;

    

     /* 私有构造子*/

     private SingletonB() {

          // CODE

     }

    

     /* 供外部调用的实例方法*/

     public static SingletonB getInstance() {

          if(null == instance) {

               instance = new SingletonB();

          }

          return instance;

     }

}

 

第三种形式:

/*

 * 单例模式---形式3

 */

public class SingletonC {

     private static SingletonC instance = null;

    

     /* 私有构造子*/

     private SingletonC() {

          // CODE

     }

    

     /* 供外界调用的实例方法 这里用到了同步*/

     public static synchronized SingletonC getInstance() {

          if(null == instance) {

               instance = new SingletonC();

          }

          return instance;

     }

}

 

当然,在这里我只列出了比较常见到的几种形式的单例,下面来具体的分析下他们之间的联系和区别,并在最后举个实际的例子来使用单例模式。具体如下所示:

对于形式1的单例模式的特点就是在单例类自己被加载的时候就将自己实例化了。但从资源的利用率角度看的话,这种方式的实现会差一点;而第二种形式的单例模式是对第一种形式的小缺点做了优化,即在加载器加载单例类时不选择创建实例对象,只有在真正需要这个单例的时候才去创建唯一的实例;如果从时间和反应的速度看的话,那么形式1的单例要比形式2的要快些。对于形式3的单例,由于它使用了同步的机制,这样势必会降低它的性能,有利也有弊,它能够很好的在异步线程中保证实例的唯一性。

总的来说,形式1和形式2更符合Java机制,就我个人习惯于第二种形式的单例模式。下面具体举个例子来说明单例的使用,当然我使用自己习惯的单例模式形式。例子是这样的,在实际项目当中,我么会经常的要获取移动设备的屏幕宽和高,那么为了便于管理和统一,我们一般选择将获取宽和高的方法封装在一个单一的类中,同时为了避免重复的创建这个类,我们选择单例模式来实现。我的代码如下:

单例模式:

/* 单例类*/

public class PhoneUtil {

     private static PhoneUtil instance = null;

     private static Context context = null;

    

     /* 私有的构造子*/

     private PhoneUtil(Context ctx) {

          context = ctx;

     }

    

     /* 供外部调用的实例化方法 保证创建唯一的实例对象*/

     public static PhoneUtil getInstance(Contextctx) {

          if(null == instance) {

               instance = new PhoneUtil(ctx);

          }

          return instance;

     }

    

     /* 获得屏幕的宽度*/

     public int getScreenWidth() {

          Display display = ((WindowManager)

                    context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

          return display.getWidth();

     }

    

     /* 获得屏幕的高度*/

     public int getScreenHeight() {

          Display display = ((WindowManager)

                    context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

          return display.getHeight();

     }

}

前端调用:

public class SingletonActivity extends Activity {

     private static String TAG = "SingletonActivity";

    

     @Override

     protected void onCreate(BundlesavedInstanceState) {

          super.onCreate(savedInstanceState);

          setContentView(R.layout.activity_singleton);

         

          int screenWidth = PhoneUtil.getInstance(this).getScreenWidth();

          log("the screen width:" + screenWidth);

         

          int screenHeight = PhoneUtil.getInstance(this).getScreenHeight();

          log("the screen height:" + screenHeight);

     }

    

     private void log(String log) {

          Log.d(TAG, log);

     }

}

代码的运行效果:

从上面的图,我的手机的屏幕宽和高分别为320和480,看来分辨率和屏幕小的可怜了!

 

好了,到这里我们基本分析和使用了常用的单例模式。

 

 

 

技术交流群:179914858

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云水之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值