导航:首页 > 操作系统 > android单例类

android单例类

发布时间:2022-11-18 01:42:18

android之单例模式:懒汉式和饿汉式的区别

比较:
饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。
懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的。

❷ android studio单例怎么使用

android studio使用单例的情况有很多,大多数是工具类,可以使用单例,里面有很多static方法,很方便的使用这些方法。

❸ Android中单例模式和静态方法在效率上哪个好

很多人包括我写单例的时候,第一想到的就是懒汉式publicclassSingleton{;privateSingleton(){}(){if(instance==null){instance=newSingleton();}returninstance;}}代码很简单,而且是懒加载,只有调用getInstance方法是才会初始化。但是这样是线程不安全的,即当多个线程并行调用getInstance的时候,就会创建多个实例,不能正常工作。所以这里就有了加锁方式,将整个getInstance方法设为同步,添加synchronized关键字。publicclassSingleton{;privateSingleton(){}(){if(instance==null){instance=newSingleton();}returninstance;}}这样简单粗暴的方式,虽然做到了线程安全,但导致了同一时间内只能有一个线程能够调用getInstance方法。其实我们仅仅需要对初始化的代码进行同步,这就有了双重检验锁方式。publicclassSingleton{;privateSingleton(){}(){if(instance==null){//第一次检查synchronized(Singleton.class){if(instance==null){//第二次检查instance=newSingleton();}}}returninstance;}}这里第二次检查,是因为如果有多个线程同时执行完了第一次检查,这时如果同步块内不进行第二次检查的话,会生成多个实例了。但是看了相关资料后,发现这样还是有点问题。引用资料中的介绍:由于instance=newSingleton(),这并非是一个原子操作,事实上在JVM中这句话大概做了下面3件事情。1.给instance分配内存2.调用Singleton的构造函数来初始化成员变量3.将instance对象指向分配的内存空间(执行完这步instance就为非null了)但是在JVM的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是1-2-3也可能是1-3-2。如果是后者,则在3执行完毕、2未执行之前,被线程二抢占了,这时instance已经是非null了(但却没有初始化),所以线程二会直接返回instance,然后使用,然后顺理成章地报错。我们只需要将instance变量声明成volatile就可以了。

❹ android 几种单例模式的写法

先不论单例模式的写法,有些方面是相同的,比如都需要将唯一的对象设置为static的,都需要将构造方法private化,代码如下:
public class MyInstance { private static MyInstance instance; private MyInstance(){}
}
第一种:最原始的单例模式,代码如下:
public static MyInstance getInstance(){ if(instance==null){ instance=new MyInstance();
} return instance;
}
多线程并发时,可能会出现重复new对象的情况,因此不提倡使用。
第二种:将整个方法块进行加锁,保证线程安全。
public static synchronized MyInstance getInstance(){ if(instance==null){ instance=new MyInstance();
} return instance;
}

这种代码下,每条线程都会依次进入方法块内部,虽然实现了单例,但是影响了运行效率,可以使用但是也不怎么提倡。
第三种:进一步优化的方法。
public static MyInstance getsInstance(){ synchronized (MyInstance.class){ if(instance==null){ instance=new MyInstance(); return instance;
}else{ return instance;
}
}
}

这种方式只是第二种方法的一种优化,但是优化有限。
(以下的几种方法比较推荐使用)
第四种:双层判断加锁,效率影响小且保证了线程安全。
public static MyInstance getsInstance() { if (instance == null) { synchronized (MyInstance.class) { if(instance==null){ instance=new MyInstance();
}
}
} return instance;
}

这种方法是对第二种和第三种方法的进一步优化,比较推荐使用。
第五种:内部类实现单例,不用线程锁来实现效率的提升。
public class MyInstance { private MyInstance() {
} public static MyInstance getInstance(){ return MyInstanceHolder.instance;
} private static class MyInstanceHolder{ private static MyInstance instance=new MyInstance();
}
}

在内部类中new对象,再将内部类的对象返回,这种方法是使用了java中class加载时互斥的原理来实现了线程的安全。不加线程锁也使得运行效率不会受到较大的影响。比较提倡。

❺ android 自定义的popupwindow,可以写成单例模式

可以啊。就像写普通的java单例类一样,构造方法私有,只能自己进行初始化,然后对外暴露一个初始化的静态方法。高级点再加上线程锁。

❻ 结合Android看看单例模式怎么写

单例模式常见的两种实现方式 饿汉模式和 双重锁模式
•饿汉模式
public class HungrySingleton {
private static HungrySingleton mInstance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return mInstance;
}
}
不得不说,饿汉模式这个名字起得的确很巧,这种方式,不管你用不用得着这个实例,先给你创建(new)出来,生怕将来创建没机会似得,完全就是今朝有酒今朝醉的节奏。
与上面对应的还有一种就是懒汉模式,就是在用的时候才在getInstance 方法中完成实例的创建(new),真是“懒”,同时给这个方法添加synchronized 关键字,可以确保在多线程情况下单例依旧唯一,但是懒汉模式每次调用getInstance 方法时由于synchronized 的存在,需要进行同步,造成不必要的资源开销。因此便有了下面双重锁模式的实现方式。
•双重锁模式(DCL 实现)
public class LazySingleton {
private static LazySingleton mInstance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (mInstance == null) {
synchronized (LazySingleton.class) {
if (mInstance == null) {
mInstance = new LazySingleton();
}
}
}
return mInstance;
}
}
这样既避免了饿汉模式的缺点,又解决了懒汉模式的不足;确保单例只在第一次真正需要的时候创建。
Android 中的使用
在日常的Android开发中,也可以见到单例模式的身影。
•Glide
使用Glide加载图片非常方便,大家应该不陌生,可以看一下它的源码中单例模式的实现方式。
Glide.with(this).load(url).into(imageView);
//Glide.with()
public static RequestManager with(FragmentActivity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
//RequestManagerRetriever.get()
/** The singleton instance of RequestManagerRetriever. */
private static final RequestManagerRetriever INSTANCE = new RequestManagerRetriever();
/**
* Retrieves and returns the RequestManagerRetriever singleton.
*/
public static RequestManagerRetriever get() {
return INSTANCE;
}
可以看到,当我们写下Glide.with(..) 这行代码时,就完成了RequestManagerRetriever 这个类的实例化,这个类的单例模式是使用饿汉模式实现的。
•EventBus
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
};
很明显,EventBus的单例模式使用双重锁模式实现的。
•InputMethodManager static InputMethodManager sInstance
public static InputMethodManager getInstance() {
synchronized (InputMethodManager.class) {
if (sInstance == null) {
IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
sInstance = new InputMethodManager(service, Looper.getMainLooper());
}
return sInstance;
}
}
InputMethodManager 的单例模式是使用懒汉模式实现。
可以看到,关于单例模式的实现方式,面对不同的场景,我们可以做出不同的选择
•Glide的单例模式虽然是使用饿汉模式实现,但理论上来说并不会造成内存资源的浪费,因为当我们通过gradle的配置引入Glide的库时,就是为了加载图片,必然会使用Glide.with进行相关的操作。同时RequestManagerRetriever 这个类应该是一个网络请求的管理类(Glide源码没有研究过,这里只是猜测),这样的一个类必然需要使用单列模式,试想如果存在多个管理类的实例,那么谈何管理,那么的多Request到底听哪个manger 的,这就是前面提到必须使用单列模式的情景。

•EventBus 作为事件总线的更要使用单例模式了,如果说EventBus的实例不是单例模式,那么他就无法实现它的功能了。对于EventBus不了解的同学,可以看看
EventBus 3.0 相见恨晚,EventBus真的很强大。

•InputMethodManager 使用懒汉模式实现单例也是无可厚非的,毕竟谁会去频繁的获取那么多他的实例呢;同时作为一个系统的输入法管理器,他也必须是唯一的,因此这个类也需要单例模式来实现它唯一的实例供外部使用。

由上可见,关于单例模式的实现,没有说哪一种方式最好,只有最合适的实现方式;实际开发中,单例模式应该怎么写,还需要根据业务场景做最合适的选择,无论是饿汉懒汉实用才是好汉。个人感觉,饿汉模式是一种简单又方便的实现方式, 一个类既然已经写成了单例模式,必然是要使用的呀,谁会去创建一个饿汉模式的单例,又不去使用这个单例呢?
之前在使用Volley的时候,就是使用饿汉模式创建整个应用的RequestQueue单例,所有需要网络请求的地方,把request添加到RequestQueue单例中即可。
public class MyApplication extends Application{
// 建立请求队列
public static RequestQueue queue;
@Override
public void onCreate() {
super.onCreate();
queue = Volley.newRequestQueue(getApplicationContext());
}
public static RequestQueue getHttpQueue() {
return queue;
}
}
在应用Application的onCreate方法中创建了属于整个应用的queue,之后每一次网络请求时,只需要queue.add(Request)即可,这里使用单例模式,可以有效的避免在多个地方创建RequestQueue 的实例,浪费系统资源。

❼ Android 你真的会用单例模式吗

会用的,在app运行过程中,你只要一个实例。如播放音乐的实例,单例为了让音乐不重叠播放!

❽ Android 开发中常用到的设计模式有哪些

2. 软件设计模式的分类
2.1. 创建型
创建对象时,不再由我们直接实例化对象;而是根据特定场景,由程序来确定创建对象的方式,从而保证更大的性能、更好的架构优势。创建型模式主要有简单工厂模式(并不是23种设计模式之一)、工厂方法、抽象工厂模式、单例模式、生成器模式和原型模式。
2.2. 结构型
用于帮助将多个对象组织成更大的结构。结构型模式主要有适配器模式adapter、桥接模式bridge、组合器模式component、装饰器模式decorator、门面模式、亨元模式flyweight和代理模式proxy。
2.3. 行为型
用于帮助系统间各对象的通信,以及如何控制复杂系统中流程。行为型模式主要有命令模式command、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式state、策略模式、模板模式和访问者模式。
3. 常见设计模式介绍
3.1. 单例模式(singleton)
有些时候,允许自由创建某个类的实例没有意义,还可能造成系统性能下降。如果一个类始终只能创建一个实例,则这个类被称为单例类,这种模式就被称为单例模式。
一般建议单例模式的方法命名为:getInstance(),这个方法的返回类型肯定是单例类的类型了。getInstance方法可以有参数,这些参数可能是创建类实例所需要的参数,当然,大多数情况下是不需要的

❾ android中什么是单例模式

单例模式(Singleton)
一、 什么是单例模式
单例模式,简单点来说就是设计一个类,使其在任何时候,最多只有一个实例,并提供一个访问这个实例的全局访问点。

二、 为什么要单例
在程序中的很多地方,只有一个实例是非常重要的。例如,在windows中,任务管理器只有一个,无论你点击多少次打开任务管理器,任务管理器也只会生成一个窗口。再例如,在一些软件中,工具箱是唯一的,无论你点击多少次打开工具箱,工具箱也只一个。

为什么要这样设计呢?因为像任务管理器或工具箱这样的程序,只要有一个就足够完成所有的工作了,多个程序只会白白消耗系统资源,而像任务管理器这类的程序还会引入多个任务管理器之间的同步问题,所以对些这些程序来说,只有一个实例或程序是必要的。

三、 为什么需要单例模式
上面讲到对于某些程序来说,保持其只有一个实例是必要的,但是如何保证一个程序或一个类只有一个实例呢?下面从类的角度来解说。

❿ 如何使用android单例模式

java模式之单例模式:
单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。
特点:
1,一个类只能有一个实例
2,自己创建这个实例
3,整个系统都要使用这个实例

Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录
数据库连接都需要这样的单线程操作。一些资源管理器常常设计成单例模式。
外部资源:譬如每台计算机可以有若干个打印机,但只能有一个Printer
Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口被两个请求同时调用。内部资源,譬如,大多数的软件都有一个(甚至多个)属性文件存放系统配置。这样的系统应当由一个对象来管理这些属性文件。

一个例子:Windows
回收站。
在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且回收站自行提供自己的实例。因此,回收站是单例模式的应用。

两种形式:
1,饿汉式单例类

public class Singleton {

private Singleton(){}

//在自己内部定义自己一个实例,是不是很奇怪?

//注意这是private 只供内部调用

private static Singleton instance =
new Singleton();

//这里提供了一个供外部访问本class的静态方法,可以直接访问

public static Singleton getInstance() {

return instance;

}

}

2,懒汉式单例类

public class Singleton {

private static Singleton instance = null;

public static synchronized Singleton
getInstance() {

//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次

//使用时生成实例,提高了效率!

if (instance==null)

instance=new Singleton();

return instance; }

}

第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy
initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。
一般来说第一种比较安全

我自己比较常用的方式:

public class Singleton {

private volatile static
Singleton singleton;

private Singleton(){}

public static Singleton getInstance(){

if(singleton==null){

synchronized(Singleton.class){

if(singleton==null){

singleton=new Singleton();

}

}

}

return singleton;

}

}

阅读全文

与android单例类相关的资料

热点内容
dvd光盘存储汉子算法 浏览:757
苹果邮件无法连接服务器地址 浏览:963
phpffmpeg转码 浏览:672
长沙好玩的解压项目 浏览:145
专属学情分析报告是什么app 浏览:564
php工程部署 浏览:833
android全屏透明 浏览:737
阿里云服务器已开通怎么办 浏览:803
光遇为什么登录时服务器已满 浏览:302
PDF分析 浏览:486
h3c光纤全工半全工设置命令 浏览:143
公司法pdf下载 浏览:382
linuxmarkdown 浏览:350
华为手机怎么多选文件夹 浏览:683
如何取消命令方块指令 浏览:350
风翼app为什么进不去了 浏览:778
im4java压缩图片 浏览:362
数据查询网站源码 浏览:151
伊克塞尔文档怎么进行加密 浏览:892
app转账是什么 浏览:163