单例模式,故名思议,是指在一个类中通过设置静态使得其仅创造一个唯一的实例。这样设置的目的是满足开发者的希望——这个类只需要被实例化创建一次,同时因为其为静态的缘故,加载的速度也应该快于正常实例化一个类的速度(理论上)。
在Android开发中,当我们需要创建一个Fragment的时候常常会用到这样的模式,没有代码的学习是虚无的,接下来亮代码学习:
public class SelectFrame extends Fragment { private final static String selectFrameKey = "SFKey"; private static SelectFrame mSelectFrame; private ArrayList<String> frameList; public static SelectFrame getInstance(ArrayList<String> frameList){ if (mSelectFrame == null) { mSelectFrame = new SelectFrame(); } Bundle bundle = new Bundle(); bundle.putStringArrayList(selectFrameKey, frameList); mSelectFrame.setArguments(bundle); return mSelectFrame; }
......
这是我在一个Fragment类里面定义的其中一部分,首先必须要定义一个自身的静态mSelectFrame。然后通过一个静态方法
getInstance()来实例化这个mSelectFrame,很明显,这里通过判断其是否为空的方式,使得每一次我们使用getInstance的时候都返回的是同一个对象mSelectFrame。
getInstance方法中有时我们也会放入一些我们需要传递的参数,比如我这个方法中放入了一个List对象,然后直接在里面用Bundle装载这个List对象,原本我们可能是在外部来做这些操作的,然而现在却直接通过这个方法将数据传入的操作集成到了这个Fragment中,即减少了外部Activity的逻辑代码,也使得这个Fragment在复用的时候操作更方便。(再通过setArguments的方法保存数据)。
接下来看我们的onCreateView方法:
@Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { view = inflater.inflate(R.layout.select_frame_fragment, container, false); Bundle bundle = mSelectFrame.getArguments(); frameList = bundle.getStringArrayList(selectFrameKey); }这里我们就将从前面getInstance中setArguments保存下来的数据通过Fragment的getArguments方法重新将数据读取出来。这样就完成了我们的目的。
接下来就是在Activity中创建我们这个Fragment对象了:
selectFrameFrag = SelectFrame.getInstance(nameFrameThumbnail); fm.beginTransaction().add(R.id.fragment_frame_container, selectFrameFrag).commit();(fm是FragmentManager..)
这样就OK了。
2.单例模式的分类
单例模式有两种创建方式,分别为饿汉式和懒汉式。
饿汉式,故名思议,很饿,在一开始就直接创建了这个对象。
懒汉式,顾名思义,很懒,只有在你要调用它的时候,通过自己写的方法里面来对他实例化。刚刚上面那个例子就是懒汉式的。
也许这么说你会有一点不明白(其实应该没有人不明白吧= =),然后其实只要看代码的这个地方:
private static SelectFrame mSelectFrame;
上面这个代码,这里一开始定义自身的静态时,没有实例化它,那么就是个懒汉.然后只有在我调用getInstance方法的时候,才在里面对他进行实例化(new
SelectFrame()).
然后我们再看看饿汉:
private static SelectFrame mSelectFrame = new SelectFrame();
在定义的时候就已经实例化了.
3.单例模式的线程安全问题
没错,单例模式毕竟就是像上面讲的这么简单。但需要注意的是,单例模式中的饿汉式是线程安全的,而懒汉式是线程不安全的,我们一般会再懒汉式的getInstance方法中通过synchronized上锁。类似于这样:
if (mSelectFrame == null) { synchronized (SelectFrame.class) { if (mSelectFrame == null) { mSelectFrame = new SelectFrame(); } } }
有人说为什么要用两个if XX == null。这里是因为提高效率,只有一个也是可以的,但效率上大大减低,因为不是每一次调用的时候我们要判断他是否同步,应该是如果判断当前为null的话,我们就直接不让他进入了,不需要判断是否同步。只有满足第一个条件的时候,我们才需要用锁来判断它是否线程安全。(这里的意思也是说明if一条语句的判断速度当然比synchronized (SelectFrame.class)快。。)
另外,在我们使用单例模式的时候,有些人会去私有化这个类的构造方法,使得这个类只能通过自己写的getInstance()来创建。类似于这样:
private SelectFrame() { // 并不需要做什么,只需要将这个外面的public改成private就好了=。= }
嗯嗯,这么一来外部就只能按我要求的方法来创建这个对象了.
在这里也基本将单例模式的使用基本讲完了,接下来还会继续写其他的设计模式的使用,如果有涉及到Android上的都会尽力用Android上的例子来讲,加深印象。
Make Life Get Better.
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u011035622/article/details/47379287