編輯:關於Android編程
所有Android的開發者一定都遇到過內存溢出這個頭疼的問題,一旦出現這個問題,很難直接確定我們的應用是那裡出了問題,要想定位問題的原因,必須通過一些內存分析工具和強大的經驗積累才能快速的定位到問題具體出現在那裡。
基於移動開發具有的這個特性,本著盡量減少內存消耗的原則,以及我最近遇到的內存堆積(偶爾溢出)問題,總結一下這次解決這個問題的經驗。
問題源頭:開始App功能沒那麼多的時候,是沒有注意到這個問題的,後來功能越強越多,圖片也越來越多的時候,用ADT自帶的Allocation Tracker查看了一下內存分配,明顯有許多無用的data object,而沒有釋放掉,開始以為是universalImageLoader的問題,以為這個開源工程對圖片的加載有問題,後來把圖片全去掉再看內存分配時還是有無用的data object,花了兩天時間後發現是,是自己本地的一些bitmap沒有回收,一直緩存在內存中,另一個原因就是前面文章提到的,為了實現退出功能,使用了一個全局的ArrayList去存儲所有新啟動的Activity,導致Activity這種大對象無法釋放,有這兩個問題內存不堆積才有問題。
定位到問題的所在後,先用前面的廣播方式替換掉之前的那種方案,這樣就解決了問題的一半了,那本地圖片如何處理呢?就上網查看了一些文章,看到許多大神都說到了軟引用這個東東,於是就研究了下軟引用如何使用。發現這軟引用的確是個好東西。的確可以優化整個應用對內存的消耗。
從JDK1.2開始,java將對象分成了四種級別,以達到程序對對象生財周期的靈活控制,這四個級別由強到弱是:強引用,軟引用,弱引用,虛引用。強引用就不多說了,就是我們平時直接new出來的一個對象,不做任何的修飾,就是強引用。虛引用暫未使用過也就沒做過深入了解,弱引用的使用方式基本和軟引用是一樣的,所以就重點看了一下應用程序如何使用軟引用。
如果一個對象只具有軟引用,那麼如果內存如果夠用的話,GC就不會回收它,如果內存不足了,就會優先回收只有軟引用的對象內存,而保證不會內存溢出。基於軟引用的這個特性,我們可以使用軟引用來實現內存敏感區的高速緩存,因此為了防止內存溢出的發生,在處理一些占用內存較大且聲明周期較長的對象的時候,我們可以盡量使用軟引用,例如: Context及其子類對象,Drawable及其子類對象,Bitmap位圖對象等,在創建這些類的對象的時候,盡量將其聲明為軟引用。
軟引用對象聲明: SoftReference
下面兩個例子是我在項目中實際使用的代碼,大家可以看下。
//這個例子是用來處理生命周期較長的大對象 /********************************************************** * @文件名稱:ActivityManager.java * @創建時間:2014年11月6日 上午11:38:23 * @文件描述:Activity管理類 * @修改歷史:2014年11月6日創建初始版本 **********************************************************/ public class ActivityManager { private static ActivityManager manager = null; private static HashMapactivityMap; // 靜態語句塊,在類加載的時候一起執行 static { manager = new ActivityManager(); activityMap = new HashMap (); } private ActivityManager() { } public static ActivityManager getInstance() { return manager; } public void put(Activity act) { activityMap.put(act.toString(), new SoftReference(act)); } public void remove(Activity act) { activityMap.remove(act.toString()); } public void finishAllActivity() { Set set = activityMap.keySet(); Iterator iter = set.iterator(); while (iter.hasNext()) { String actName = iter.next(); Activity currentAct = activityMap.get(actName).get(); if (currentAct != null) { currentAct.finish(); currentAct = null; } } activityMap.clear(); activityMap = null; } }
//這個例子是用來處理位圖等內存敏感對象示例 public class BitmapManager { private static BitmapManager bitmapManager = null; private static HashMap總結:在我們開發應用程序時,最好是剛開始實現時就考慮到可能發生的問題,提前就做好這些細節性的處理,就會從根上杜絕這類問題的發生,而當問題發生了再去處理就會花費更多的精力。> imageCache = null; static { bitmapManager = new BitmapManager(); imageCache = new HashMap >(); } private BitmapManager() { } public static BitmapManager getInstance() { return bitmapManager; } public static void saveBitmapToCache(String path) { Bitmap bitmap = BitmapFactory.decodeFile(path); // 添加該對象軟引用對象到Map中使其緩存 imageCache.put(path, new SoftReference (bitmap)); // 使用完後手動將位圖對象置null bitmap = null; } public static Bitmap queryBitmapByPath(String path) { // 取出軟軟引用 SoftReference softBitmap = imageCache.get(path); // 使用時必須判斷軟引用是否回收,被回收返回空 if (softBitmap == null) { return null; } Bitmap bitmap = softBitmap.get(); return bitmap; } }
最近兩天為了測試使用ffmpeg獲取視頻圖片的效率問題,玩了一把ffmpeg的移植工作. 在這裡作下記錄。所有測試都只在mac系統中測試。 1. 下載ffmpe
shape和selector是Android UI設計中經常用到的,比如我們要自定義一個圓角Button,點擊Button有些效果的變化,就要用到shape和select
有時候作為非官方開發的APP集成了官方的所有信息,但是現在需要實現另一個功能那就是登錄發表評論到官方的網站,而非官方的APP並不知道官方網站是怎麼實現登錄與評論的,而且越
本文實例講述了Android編程之SharedPreferences文件存儲操作的方法。分享給大家供大家參考。具體分析如下:SharedPreferences類提供了一種