① android之單例模式:懶漢式和餓漢式的區別
比較:
餓漢式是線程安全的,在類創建的同時就已經創建好一個靜態的對象供系統使用,以後不在改變。
懶漢式如果在創建實例對象時不加上synchronized則會導致對對象的訪問不是線程安全的。
② 結合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 開發中常用到的設計模式有哪些
Builder模式:比如AlertDialog.Builder。
適配器模式:比如GridView、ListView與Adapter。
命令模式:比如Handler.post。
享元模式:比如Message.obtain。
單例模式:比如InputMethodManager.getInstance。
觀察者模式:比如ContentObserver。
這是一些經常用到的設計模式以及舉例。
④ 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 service是單例嗎
android service不存在單列的問題,service是安卓一個組件。單例是一種設計模式。
1、在實際運行中同樣的Service的確只能有一個。
2、Service類沒有必要運用單例模式。
⑦ 如何使用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應用程序,非常好用
首先問題是這樣的,比如:我剛進入應用時有一個歡迎頁面(E),隨後進入主A,我從A->B->C->D,然後直接從D返回到A,在A中完全退出應用。對於android自帶的1.5 - 2.1以及2.2之後完全退出應用的API我都試了,但還是實現不了,有的是能退出,但是歡迎頁面就沒有了,可能是我的原因。 後來我是這樣實現的,當然有點老土,但還是能實現的。如下,同樣也歡迎拍磚
public class ExitApplication extends Application {
//存儲已打開的Activity集合
private List<Activity> list = new ArrayList<Activity>();
//單例的ExitApplication,目的是在任何的Activity中用的都是同一個集合
private static ExitApplication ea;
private ExitApplication(){
}
public static ExitApplication getInstance(){
if(null==ea){
ea = new ExitApplication();
}
return ea;
}
/**
* 添加Activity到集合中
*/
public void addActivity(Activity activity){
list.add(activity);
}
public void exit(Context context){
Dialog dialog = new AlertDialog.Builder(context).setTitle("確認退出")
.setMessage("確定退出該系統?")
.setPositiveButton("確定",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
for(Activity activity:list){
activity.finish();
}
System.exit(0);
}
}).setNegativeButton("取消",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
}
}).create();
dialog.show();
}
}
我這個必須是單例的,因為我要確保把每個UI都加進一個集合中,所以...,至於對單例有疑問的,可以上網查詢,
然後在每個Activity的onCreate方法中調用ExitApplication.getInstance().addActivity(this);,然後在處理退出請求中直接調用ExitApplication.getInstance().exit(this);即可。
轉載