標籤:
正式接觸android我們一直在開發了一段時間,該項目的第一個版本最終會很快結束。
當有它自己的測試。擁有android後台。同一時候開啟了幾個應用之後又一次切回到自己的app。發現報錯了。經過排查,發現是自己的單例對象中的資料被釋放掉了,也就是int變數的值 變成了0,string變數的值變成了null。
我的單例一開始是這種(舉例);
public class UserInfo {private static UserInfo userInfo = null;private int level;private UserInfo() { <span style="white-space:pre"></span>}public static UserInfo getInstance() {if (null == userInfo) {userInfo = new UserInfo();}return userInfo;}public void setLevel(int level){this.level = level;}public int getLevel(){return level;}}
這應該是一個比較普通的單例類。用來儲存我們常常使用的變數。平時我的使用是沒有問題的。在各個activity。fragment裡都能夠正常使用,如以下程式碼片段:
if(UserInfo.getInstance().getLevel() == 3){//我們的代碼塊}
可是,當我使用我的測試機(測試機是512m記憶體)進行測試的時候,首先把android應用切到後台,開啟多個其它的app如qq等,再把我們的應用恢複到前台的時候,上面範例的代碼塊居然沒有進入,我通過列印調試發現getLevel()的值已經是0了,也就是被釋放了。
我google了一下,有些人在android上使用像我這種單例是沒問題的。而有些人則會說自己的單例被釋放了。也就是和我的情況一樣。
可能是因為手機記憶體吃緊,我們單例Object Storage Service的資料被迫被釋放了。
以下就要找到這個問題的解決方案。
(1)使用android application 。這種方法本來我是想使用的,可是大概查了一下。比如這篇文章:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0204/2409.html
發現最好不要使用這樣的方法,甚至文章裡寫了都不要使用單例~~我自己試了一下,感覺問題依舊存在。
(2)onSaveInstanceState() 和 onRestoreInstanceState()。當我發生這個問題的時候,都是android強制性的移除了我當前的activity。可能同一時候釋放了我的單例對象中的資料。
我也的確運行了onSaveInstanceState()函數。同一時候在切回來的時候運行了onRestoreInstanceState()重繪我的activity,那麼我能夠在onSaveInstanceState() 裡儲存我的單例資料,然後在onRestoreInstanceState()裡對我的資料進行又一次賦值。這樣貌似也是能夠的,可是。這種話,單例用起來就太那啥了,感覺都不須要單例了。
。
(3)使用SharedPreferences來進行存取資料的操作。當我們為資料賦值和取出資料的時候,最好還是用以下的代碼:
<span style="white-space:pre"></span>public void setLevel(int level, Context context){saveSharedPreferences(context, "level", level+"");this.level = level;}public int getLevel(Context context){level = Integer.parseInt(Utils.readSharedPreferences(context, "level"));return level;}
<span style="white-space:pre"></span>public static void saveSharedPreferences(Context context, String name, String data) {SharedPreferences sharedPreferences = context.getSharedPreferences("school_user_info", Context.MODE_PRIVATE);SharedPreferences.Editor editor = sharedPreferences.edit();editor.putString(name, data);editor.commit();}public static String readSharedPreferences(Context context, String name) {SharedPreferences sharedPreferences = context.getSharedPreferences("school_user_info", Context.MODE_MULTI_PROCESS);return sharedPreferences.getString(name, "");}
在為單例對象中的資料賦值的時候。把這個資料存放在preference中,使用的時候,再從preference中取出我的值,進行對應的操作,這樣做的話,即使當我的單例被釋放了。我依然能夠從preference中取出資料。這樣做之後,我發現自己之前的bug就消失了,不會由於資料為空白導致各種各樣的錯誤了。
可是。細緻想一下。發現這樣做的話單例模式在這裡使用就略有多餘,我直接存取preference就能夠了。幹嘛還要這樣寫呢?由於項目進度較為緊迫,我僅僅好用(3)方法改動了一下My Code保證了其沒有這種bug。可是這樣做以我如今的眼光來看。並非很好,感覺造成了代碼的多餘。可是單例模式是我們的工作中使用最頻繁的設計的圖案。在中學的時候,我們經常用它,它是在android當你不能這樣使用一個單一的情況下做的?我是持懷疑態度。
我不知道,我還沒有遇到過同樣的問題,假設滿足,而如何解決呢?如何androidSingleton模式用它?我希望有一種方式培養學生良好的能分享他們的觀點~
android在單身的對象和一些資料的問題被釋放