情境
假設我們有一個物件,要如何把它從目前的activity丟到另外一個activity,
上網查,找到了一個設計模式叫做 Singleton 真的超好用的,
程式碼說明
簡單說明一下
假設有一個類別, 在目前的Activity裡面設定好狀態了,
但是你又想讓這個類別保留著, 然後到另外一個Activity裡面拿出來用,
這時候你該怎麼辦呢? 這時候你會想到靜態類別, 但是你要如何能夠保證,
你生出來的類別,不會被濫用呢?
這時候Singleton就是一個好方法。
它可以讓你只產生一個物件。
假設你有一個類別 叫做Singleton長這樣
class Singleton{
public Singleton(){}
}
那你想要建立這個類別的物件
你可能會這樣做
Singleton single = new Singleton();
但是如果你要讓別人沒辦法自由的建立這個類別的物件
你可以這樣做
class Singleton{
private Singleton(){}
}
那這樣誰能夠存取?
當然只剩下自己能夠存取囉!
所以接下來你可以這樣寫,
class Singleton{
private static Singleton single;
private Singleton(){}
public static Singleton getInstance(){
single = new Singleton();
}
return single;
}
如此一來, 只要呼叫Singleton.getInstance()就可以產生一個物件了。
可是這樣又不太對, 如果每個人都一直呼叫A.getInstance();
不就還是建立一堆物件, 所以加上幾行限制
class Singleton{
private static Singleton single;
private Singleton(){}
public static Singleton getInstance(){
if(single == null){
single = new Singleton();
}
return single;
}
}
這樣一來, 就只能產生一個物件, 可是這時候卻又出現了一個問題,
假設有兩個執行緒同時存取這個類別的getInstance這個方法,
如果我們的直行順序變成這樣:
A 執行緒 跑到了 第五行 時間到了
B 執行緒 跑到了 第五行 時間到了
A 執行緒 在第六行 建立一個物件。
B 執行緒 在第六行 建立一個物件。
違反 Singleton的原則 : 只建立一個物件。
所以我們只需要將getInstance() 變成一個同步化的方法, 就可以將上面的問題解決掉了。
class Singleton{
private static Singleton single;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(single == null){
single = new Singleton();
}
return single;
}
}
ya, 解決了。
並沒有。
synchronized是很耗效能的, 如果大量的呼叫這個方法, 你的電腦會有一群耗能執行緒再折磨你的電腦,而且這些並沒有意義, 其實如果第一次完成new以後, 根本不需要再對getInstance做同步了。
所以又開發了一個想法, 那如果我們一開始程式就幫你把物件new好了呢?
class Singleton{
private static Singleton single = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return single;
}
}
這樣一來, 雖然少了Lazy Initialization(延遲出屎化初始化:需要用到物件的時候才建立),
如果你的類別不是吃很大的資源,其實這樣就很夠用了。
那我們回到原本的題目: 如何讓一個物件在很多個activity穿梭呢?
假設你寫了一個貓類別
class Cat{
private static Cat candy = new Cat();
private Cat(){}
public static Cat getMyCat(){
return candy;
}
//其他方法
}
然後在A activity
public class A extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cat candy = Cat.getMyCat();
//作一些設定
Intent i = new Intent();
i.setClass(A.this, B.class);
startActivity(i);//跳到B頁面
}
}
然後在B activity display
public class B extends Activity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Cat candy = Cat.getMyCat();
//取得一些資訊
//display
}
}
這樣表示無論你在哪裡就可以存取Cat類別的物件,
也等同於,把某個物件傳到另外一個Activity。