編輯:關於Android編程
內存洩露可以引發很多的問題:
1.程序卡頓,響應速度慢(內存占用高時JVM虛擬機會頻繁觸發GC)
2.莫名消失(當你的程序所占內存越大,它在後台的時候就越可能被干掉。反之內存占用越小,在後台存在的時間就越長)
3.直接崩潰(OutOfMemoryError)
ANDROID內存面臨的問題:
1.有限的堆內存,原始只有16M
2.內存大小消耗等根據設備,操作系統等級,屏幕尺寸的不同而不同
3.程序不能直接控制
4.支持後台多任務處理(multitasking)
5.運行在虛擬機之上
我主要通過以下的5個方面(5R)來對ANDROID內存進行優化:
1.Reckon(計算)首先需要知道你的app所消耗內存的情況,知己知彼才能百戰不殆
2.Reduce(減少)消耗更少的資源
3.Reuse(重用)當第一次使用完以後,盡量給其他的使用
4.Recycle(回收)返回資源給生產流
5.Review(檢查)回顧檢查你的程序,看看設計或代碼有什麼不合理的地方。
下面就從這幾個方面詳細說一下:
一、Reckon(計算)
了解自己應用的內存使用情況是很有必要的。如果當內存使用過高的話就需要對其進行優化,因為更少的使用內存可以減少ANDROID系統終止我們的進程的幾率,也可以提高多任務執行效率和體驗效果。下面從系統內存(system ram)和堆內存(heap)兩個方面介紹一些查看和計算內存使用情況的方法:
1.System Ram(系統內存):
觀察和計算系統內存使用情況,可以使用Android提供給我們的兩個工具procstats,meminfo。他們一個側重於後台的內存使用,另一個是運行時的內存使用。
(1)Process Stats:
Android 4.4 KitKat 提出了一個新系統服務,叫做procstats。它將幫助你更好的理解你app在後台(background)時的內存使用情況。
Procstats可以去監視你app在一段時間的行為,包括在後台運行了多久,並在此段時間使用了多少內存。從而幫助你快速的找到應用中不效率和不規范的地方去避免影響其performs,尤其是在低內存的設備上運行時。
你可以通過adb shell命令去使用procstats(adb shell dumpsys procstats –hours 3),或者更方便的方式是運行Process Stats開發者工具(在4.4版本的手機中點擊Settings > Developer options > Process Stats)
點擊單個條目還可以查看詳細信息
(2)meminfo:
Android還提供了一個工具叫做meminfo。它是根據PSS標准 (PropZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcnRpb25hbCBTZXQgU2l6ZSZtZGFzaDsmbWRhc2g7yrW8ys7vwO3E2rTmo6m8xsvjw7+49r34s8y1xMTatObKudPDsqLH0rC01dXW2NKqs8y2yMXF0PKhozxiciAvPg0KxOO/ydLUzai5/cP8we7Q0Mil1rTQ0Mv8o7qjqGFkYiBzaGVsbCBkdW1wc3lzIG1lbWluZm+jqbvy1d/KudPD1NrJ6LG4yc+147v3U2V0dGluZ3MgJmd0OyBBcHBzICZndDsgUnVubmluZ6Oo0+tQcm9jc3RhdHOyu9PDo6zL/NKyv8nS1NTawM+w5rG+yc/Uy9DQo6k8YnIgLz4NCjIuSGVhcKOottHE2rTmo6mjujxiciAvPg0K1NqzzNDy1tC/ydLUyrnTw8jnz8K1xLe9t6jIpbLp0a/E2rTmyrnTw8fpv/Y8YnIgLz4NCqOoMaOpQWN0aXZpdHlNYW5hZ2VyI2dldE1lbW9yeUNsYXNzKCk8YnIgLz4NCrLp0a+/ydPDttHE2rTmtcTP3tbGo6wzLjAoSG9uZXlDb21iKdLUyc+1xLDmsb6/ydLUzai5/WxhcmdlSGVhcD0mbGRxdW87dHJ1ZSZyZHF1bzvAtMnqx+u4/LbgtcS20cTatOajqLK7uf3V4svj1/cmbGRxdW871/ex1yZyZHF1bzujqTxiciAvPg0Ko6gyo6lBY3Rpdml0eU1hbmFnZXIjZ2V0TWVtb3J5SW5mbyhBY3Rpdml0eU1hbmFnZXIuTWVtb3J5SW5mbyk8YnIgLz4NCrXDtb21xE1lbW9yeUluZm/W0L/J0tSy6b+0yOfPwkZpZWxktcTK9NDUo7o8YnIgLz4NCmF2YWlsTWVtOrHtyr7Ptc2zyqPT4MTatOY8YnIgLz4NCmxvd01lbW9yeaO6y/zKx2Jvb2xlYW7WtaOsse3Kvs+1zbPKx7fxtKbT2rXNxNq05tTL0NA8YnIgLz4NCmhyZXNob2xko7rL/LHtyr61sc+1zbPKo9PgxNq05rXN09q6w7bgyrG+zb+0s8m1zcTatObUy9DQPGJyIC8+DQqjqDOjqWFuZHJvaWQub3MuRGVidWcjZ2V0TWVtb3J5SW5mbyhEZWJ1Zy5NZW1vcnlJbmZvIG1lbW9yeUluZm8pPGJyIC8+DQq1w7W9tcRNZW1vcnlJbmZv1tC/ydLUsum/tMjnz8JGaWVsZLXEyvTQ1KO6PGJyIC8+DQpkYWx2aWtQcml2YXRlRGlydHmjuiBUaGUgcHJpdmF0ZSBkaXJ0eSBwYWdlcyB1c2VkIGJ5IGRhbHZpa6GjPGJyIC8+DQpkYWx2aWtQc3Mgo7pUaGUgcHJvcG9ydGlvbmFsIHNldCBzaXplIGZvciBkYWx2aWsuPGJyIC8+DQpkYWx2aWtTaGFyZWREaXJ0eSCjulRoZSBzaGFyZWQgZGlydHkgcGFnZXMgdXNlZCBieSBkYWx2aWsuPGJyIC8+DQpuYXRpdmVQcml2YXRlRGlydHkgo7pUaGUgcHJpdmF0ZSBkaXJ0eSBwYWdlcyB1c2VkIGJ5IHRoZSBuYXRpdmUgaGVhcC48YnIgLz4NCm5hdGl2ZVBzcyCjulRoZSBwcm9wb3J0aW9uYWwgc2V0IHNpemUgZm9yIHRoZSBuYXRpdmUgaGVhcC48YnIgLz4NCm5hdGl2ZVNoYXJlZERpcnR5IKO6VGhlIHNoYXJlZCBkaXJ0eSBwYWdlcyB1c2VkIGJ5IHRoZSBuYXRpdmUgaGVhcC48YnIgLz4NCm90aGVyUHJpdmF0ZURpcnR5IKO6VGhlIHByaXZhdGUgZGlydHkgcGFnZXMgdXNlZCBieSBldmVyeXRoaW5nIGVsc2UuPGJyIC8+DQpvdGhlclBzcyCjulRoZSBwcm9wb3J0aW9uYWwgc2V0IHNpemUgZm9yIGV2ZXJ5dGhpbmcgZWxzZS48YnIgLz4NCm90aGVyU2hhcmVkRGlydHkgo7pUaGUgc2hhcmVkIGRpcnR5IHBhZ2VzIHVzZWQgYnkgZXZlcnl0aGluZyBlbHNlLjxiciAvPg0KZGFsdmlro7rKx9a4ZGFsdmlry/nKudPDtcTE2rTmoaM8YnIgLz4NCm5hdGl2ZaO6ysexu25hdGl2ZbbRyrnTw7XExNq05qGj06a4w9a4yrnTw0NcQysr1Nq20cnPt9bF5LXExNq05qGjPGJyIC8+DQpvdGhlcjrKx9a4s/1kYWx2aWu6zW5hdGl2Zcq508O1xMTatOaho7Wryse+38zlysfWuMqyw7TE2KO/1sHJ2bD8wKjU2kNcQysrt9bF5LXEt8e20cTatOajrLHIyOe31sXk1NrVu8nPtcTE2rTmoaM8YnIgLz4NCnByaXZhdGU6ysfWuMu909C1xKGjt8e5ss/ttcShozxiciAvPg0Kc2hhcmU6ysfWuLmyz+21xMTatOahozxiciAvPg0KUFNTo7rKtbzKyrnTw7XEzu/A7cTatOajqLHIwP231sXkubLP7b/i1bzTw7XExNq05qOpPGJyIC8+DQpQcml2YXRlRGlydHmjusv8ysfWuLfHubLP7bXEo6zT1rK7xNy7u9Kzs/bIpaOoY2FuIG5vdCBiZSBwYWdlZCB0byBkaXNrIKOptcTE2rTmtcS089ChoaOxyMjnTGludXjOqsHLzOG437fWxeTE2rTmy9m2yLb4u7qz5bXE0KG21M/zo6y8tMq5xOO1xL34s8y94cr4o6y4w8TatObSsrK7u+HKzbfFtfSjrMv81rvKx9PW1tjQwrvYtb27urPl1tC2+NLRoaM8YnIgLz4NClNoYXJlZERpcnR5OrLO1dVQcml2YXRlRGlydHnO0sjPzqrL/NOmuMPKx9a4ubLP7bXEo6zT1rK7xNy7u9Kzs/bIpaOoY2FuIG5vdCBiZSBwYWdlZCB0byBkaXNrIKOptcTE2rTmtcS089ChoaOxyMjnTGludXjOqsHLzOG437fWxeTE2rTmy9m2yLb4u7qz5bXE0KG21M/zo6y8tMq5y/nT0Lmyz+3L/LXEvfizzL3hyvijrLjDxNq05tKysru74crNt8W19KOsy/zWu8rH09bW2NDCu9i1vbu6s+XW0Lb40tGhozxiciAvPg0Ko6g0o6lhbmRyb2lkLm9zLkRlYnVnI2dldE5hdGl2ZUhlYXBTaXplKCk8YnIgLz4NCre1u9i1xMrHtbHHsL34s8xuYXZ0aXZlttGxvsnt19y1xMTatOa089ChPGJyIC8+DQqjqDWjqWFuZHJvaWQub3MuRGVidWcjZ2V0TmF0aXZlSGVhcEFsbG9jYXRlZFNpemUoKTxiciAvPg0Kt7W72LXEyse1scewvfizzG5hdnRpdmW20dbQ0tHKudPDtcTE2rTmtPPQoTxiciAvPg0Ko6g2o6lhbmRyb2lkLm9zLkRlYnVnI2dldE5hdGl2ZUhlYXBGcmVlU2l6ZSgpPGJyIC8+DQq3tbvYtcTKx7Wxx7C9+LPMbmF2dGl2ZbbR1tDS0b6tyqPT4LXExNq05rTz0KE8YnIgLz4NCqOoN6OpTWVtb3J5IEFuYWx5c2lzIFRvb2yjqE1BVKOpo7o8YnIgLz4NCs2os6PE2rTm0LnCtrfWzvaxu8jPzqrKx9K7vP663NPQxNG2yLXEuaTX96Os0ruw49PJzcW209bQtcTXysnuyMvKv7340NCho7K7uf2jrL3xzOzO0sPH0qq96cnctcQgTUFUo6hFY2xpcHNlIE1lbW9yeSBBbmFseXplcqOpsbvIz86qysfSu7j2JmxkcXVvO8m1uc/KvSZsZHF1bzu1xLbR16q0os7EvP631s72uaS+36OsxOPWu9Do0qrH4cfhteO799K7z8LK87Hqvs2/ydLUyfqzydK7uPbXqNK1tcS31s72sai45qGjPGJyIC8+DQrI58/CzbyjujxiciAvPg0KPGltZyBhbHQ9"這裡寫圖片描述" src="/uploadfile/Collfiles/20160716/201607160921091016.png" title="\" />
二、Reduce(減少)主要通過以下方法減少內存使用:
(一)Bitmap:
Bitmap是內存消耗大戶,絕大多數的OOM崩潰都是在操作Bitmap時產生的,下面來看看如何幾個處理圖片的方法:
(1)圖片顯示:根據需求去加載圖片的大小。例如在列表中僅用於預覽時加載縮略圖(thumbnails ),只有當用戶點擊具體條目想看詳細信息的時候,才顯示整個圖片
(2)圖片大小:直接使用ImageView顯示bitmap會占用較多資源,特別是圖片較大的時候,可能導致崩潰。使用BitmapFactory.Options設置inSampleSize, 這樣做可以減少對系統資源的要求。屬性值inSampleSize表示縮略圖大小為原始圖片大小的幾分之一,即如果這個值為2,則取出的縮略圖的寬和高都是原始圖片的1/2,圖片大小就為原始大小的1/4。
(3)圖片像素:Android中圖片有四種屬性,分別是:
ALPHA_8:每個像素占用1byte內存
ARGB_4444:每個像素占用2byte內存
ARGB_8888:每個像素占用4byte內存 (默認)
RGB_565:每個像素占用2byte內存
Android默認的顏色模式為ARGB_8888,這個顏色模式色彩最細膩,顯示質量最高。但同樣的,占用的內存也最大。 所以在對圖片效果不是特別高的情況下使用RGB_565(無透明度),或者ARGB_4444(有透明度)
(4)圖片回收:使用Bitmap過後,就需要及時的調用Bitmap.recycle()方法來釋放Bitmap占用的內存空間,而不要等Android系統來進行釋放。
(5)捕獲異常:經過上面這些優化後還會存在報OOM的風險,所以下面需要一道最後的關卡——捕獲OOM異常
(二)修改對象引用類型:
引用分為四種級別,這四種級別由高到低依次為:強引用>軟引用>弱引用>虛引用。
如果只是想避免OutOfMemory異常的發生,則可以使用軟引用。如果對於應用的性能更在意,想盡快回收一些占用內存比較大的對象,則可以使用弱引用。
自Android2.3版本(API Level 9)開始,垃圾回收器更著重於對軟/弱引用的回收,對於軟引用或者弱引用的Bitmap緩存方案,現在已經不推薦使用了。
(三)其他減少內存使用的方法
(1)對常量使用static final修飾符
(2)靜態方法代替虛擬方法
(3)減少不必要的全局變量
(4)避免創建不必要的對象
(5)避免內部Getters/Setters
(6)避免使用浮點數
(7)使用實體類比接口好
(8)免使用枚舉
(9)for循環時,訪問成員變量比訪問本地變量慢得多,永遠不要在for的第二個條件中調用任何方法,在java1.5中引入的for-each語法(例如for (Foo a : mArray))編譯器還會在每次循環中產生一個額外的對本地變量的存儲操作(如上面例子中的變量a),這樣會比普通循環多出4個字節,速度要稍微慢一些
(10)了解並使用類庫
三、Reuse(重用)
重用是減少內存消耗的重要手段之一,核心思路就是將已經存在的內存資源重新使用而避免去創建新的,最典型的使用就是緩存(Cache)和池(Pool)。
(一)Bitmap緩存:Bitmap緩存分為兩種:一種是內存緩存,一種是硬盤緩存。
內存緩存(LruCache):
以犧牲寶貴的應用內存為代價,內存緩存提供了快速的Bitmap訪問方式。系統提供的LruCache類是非常適合用作緩存Bitmap任務的,它將最近被引用到的對象存儲在一個強引用的LinkedHashMap中,並且在緩存超過了指定大小之後將最近不常使用的對象釋放掉。
注意:以前有一個非常流行的內存緩存實現是SoftReference(軟引用)或者WeakReference(弱引用)的Bitmap緩存方案,然而現在已經不推薦使用了。自Android2.3版本(API Level 9)開始,垃圾回收器更著重於對軟/弱引用的回收,這使得上述的方案相當無效。
硬盤緩存(DiskLruCache):
一個內存緩存對加速訪問最近浏覽過的Bitmap非常有幫助,但是你不能局限於內存中的可用圖片。GridView這樣有著更大的數據集的組件可以很輕易消耗掉內存緩存。你的應用有可能在執行其他任務(如打電話)的時候被打斷,並且在後台的任務有可能被殺死或者緩存被釋放。一旦用戶重新聚焦(resume)到你的應用,你得再次處理每一張圖片。
在這種情況下,硬盤緩存可以用來存儲Bitmap並在圖片被內存緩存釋放後減小圖片加載的時間(次數)。當然,從硬盤加載圖片比內存要慢,並且應該在後台線程進行,因為硬盤讀取的時間是不可預知的。
注意:如果訪問圖片的次數非常頻繁,那麼ContentProvider可能更適合用來存儲緩存圖片,例如Image Gallery這樣的應用程序。更多關於內存緩存和硬盤緩存的內容請看Google官方教程https://developer.android.com/develop/index.html
(二)圖片緩存的開源項目:
對於圖片的緩存現在都傾向於使用開源項目,這裡我列出幾個我搜到的:
1. Android-Universal-Image-Loader 圖片緩存
目前使用最廣泛的圖片緩存,支持主流圖片緩存的絕大多數特性。
項目地址:https://github.com/nostra13/Android-Universal-Image-Loader
2. picasso square開源的圖片緩存
項目地址:https://github.com/square/picasso
特點:
(1)可以自動檢測adapter的重用並取消之前的下載
(2)圖片變換
(3)可以加載本地資源
(4)可以設置占位資源
(5)支持debug模式
3. ImageCache 圖片緩存,包含內存和Sdcard緩存
項目地址:https://github.com/Trinea/AndroidCommon
特點:
(1)支持預取新圖片,支持等待隊列
(2)包含二級緩存,可自定義文件名保存規則
(3)可選擇多種緩存算法(FIFO、LIFO、LRU、MRU、LFU、MFU等13種)或自定義緩存算法
(4)可方便的保存及初始化恢復數據
(5)支持不同類型網絡處理
(6)可根據系統配置初始化緩存等
4. Android 網絡通信框架Volley
項目地址:https://android.googlesource.com/platform/frameworks/volley
我們在程序中需要和網絡通信的時候,大體使用的東西莫過於AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,在2013年的Google I/O發布了Volley。Volley是Android平台上的網絡通信庫,能使網絡通信更快,更簡單,更健壯。
特點:
(1)JSON,圖像等的異步下載;
(2)網絡請求的排序(scheduling)
(3)網絡請求的優先級處理
(4)緩存
(5)多級別取消請求
(6)和Activity和生命周期的聯動(Activity結束時同時取消所有網絡請求)
(三)Adapter適配器
在Android中Adapter使用十分廣泛,特別是在list中。所以adapter是數據的 “集散地” ,所以對其進行內存優化是很有必要的。主要使用convertView和ViewHolder來進行緩存處理
(四)池(PooL)
1.對象池:
對象池使用的基本思路是:將用過的對象保存起來,等下一次需要這種對象的時候,再拿出來重復使用,從而在一定程度上減少頻繁創建對象所造成的開銷。 並非所有對象都適合拿來池化――因為維護對象池也要造成一定開銷。對生成時開銷不大的對象進行池化,反而可能會出現“維護對象池的開銷”大於“生成新對象的開銷”,從而使性能降低的情況。但是對於生成時開銷可觀的對象,池化技術就是提高性能的有效策略了。
2.線程池:
線程池的基本思想還是一種對象池的思想,開辟一塊內存空間,裡面存放了眾多(未死亡)的線程,池中線程執行調度由池管理器來處理。當有線程任務時,從池中取一個,執行完成後線程對象歸池,這樣可以避免反復創建線程對象所帶來的性能開銷,節省了系統的資源。
比如:一個應用要和網絡打交道,有很多步驟需要訪問網絡,為了不阻塞主線程,每個步驟都創建個線程,在線程中和網絡交互,用線程池就變的簡單,線程池是對線程的一種封裝,讓線程用起來更加簡便,只需要創一個線程池,把這些步驟像任務一樣放進線程池,在程序銷毀時只要調用線程池的銷毀函數即可。java提供了ExecutorService和Executors類,我們可以應用它去建立線程池。
(五)注意:要根據情況適度使用緩存,因為內存有限。能保存路徑地址的就不要存放圖片數據,不經常使用的盡量不要緩存,不用時就清空。
四、Recycle(回收)
回收可以說是在內存使用中最重要的部分。因為內存空間有限,無論你如何優化,如何節省內存總有用完的時候。而回收的意義就在於去清理和釋放那些已經閒置,廢棄不再使用的內存資源和內存空間。
(一)垃圾回收(GC):
1、Java垃圾回收器:
Java技術提供了一個系統級的線程,即垃圾收集器線程(Garbage Collection Thread),來跟蹤每一塊分配出去的內存空間,當Java 虛擬機(Java Virtual Machine)處於空閒循環時,垃圾收集器線程會自動檢查每一快分配出去的內存空間,然後自動回收每一快可以回收的無用的內存塊。
2、作用:
1.清除不用的對象來釋放內存:
2.消除堆內存空間的碎片:
3、垃圾回收器優點:
1.減輕編程的負擔,提高效率:
2.它保護程序的完整性:
4、垃圾回收器缺點:
1.占用資源時間:
2.不可預知:
3.不確定性:
4.不可操作
5、finalize():
每一個對象都有一個finalize方法,這個方法是從Object類繼承來的。
當垃圾回收確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。
Java 技術允許使用finalize方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。一旦垃圾回收器准備好釋放對象占用的空間,將首先調用其finalize()方法,並且在下一次垃圾回收動作發生時,才會真正回收對象占用的內存。
簡單的說finalize方法是在垃圾收集器刪除對象之前對這個對象調用的
6、System.gc():
我們可以調用System.gc方法,建議虛擬機進行垃圾回收工作(注意,是建議,但虛擬機會不會這樣干,我們也無法預知!)
總之,在Java語言中,判斷一塊內存空間是否符合垃圾收集器收集的標准只有兩個:
1.給對象賦予了空值null,以下再沒有調用過。
2.給對象賦予了新值,既重新分配了內存空間。
最後再次提醒一下,一塊內存空間符合了垃圾收集器的收集標准,並不意味著這塊內存空間就一定會被垃圾收集器收集。
(二)資源的回收:
1、Thread(線程)回收:
線程中涉及的任何東西GC都不能回收(Anything reachable by a thread cannot be GC’d ),所以線程很容易造成內存洩露。因為運行中的線程是稱之為垃圾回收根(GC Roots)對象的一種,不會被垃圾回收。當垃圾回收器判斷一個對象是否可達,總是使用垃圾回收根對象作為參考點。
2、Cursor(游標)回收:
Cursor是Android查詢數據後得到的一個管理數據集合的類,在使用結束以後。應該保證Cursor占用的內存被及時的釋放掉,而不是等待GC來處理。並且Android明顯是傾向於編程者手動的將Cursor close掉,因為在源代碼中我們發現,如果等到垃圾回收器來回收時,會給用戶以錯誤提示。
有一種情況下,我們不能直接將Cursor關閉掉,這就是在CursorAdapter中應用的情況,但是注意,CursorAdapter在Acivity結束時並沒有自動的將Cursor關閉掉,因此,你需要在onDestroy函數中,手動關閉。
(三)Receiver(接收器)回收
調用registerReceiver()後未調用unregisterReceiver().
當我們Activity中使用了registerReceiver()方法注冊了BroadcastReceiver,一定要在Activity的生命周期內調用unregisterReceiver()方法取消注冊
也就是說registerReceiver()和unregisterReceiver()方法一定要成對出現,通常我們可以重寫Activity的onDestory()方法取消注冊
(四)Stream/File(流/文件)回收:
主要針對各種流,文件資源等等如:
InputStream/OutputStream,SQLiteOpenHelper,SQLiteDatabase,Cursor,文件,I/O,Bitmap圖片等操作等都應該記得顯示關閉。
五、Review(檢查)
主要目的就是檢查代碼中存在的不合理和可以改進的地方
(一)Code Review(代碼檢查):
Code Review主要檢查代碼中存在的一些不合理或可以改進優化的地方。
(二)UI Review(視圖檢查):
Android對於視圖中控件的布局渲染等會消耗很多的資源和內存,所以這部分也是我們需要注意的。
1、減少視圖層級:
減少視圖層級可以有效的減少內存消耗,因為視圖是一個樹形結構,每次刷新和渲染都會遍歷一次。
1.hierarchyviewer:想要減少視圖層級首先就需要知道視圖層級,所以下面介紹一個SDK中自帶的一個非常好用的工具hierarchyviewer。
你可以在下面的地址找到它:\sdk path\sdk\tools
如上圖大家可以看到,hierarchyviewer可以非常清楚的看到當前視圖的層級結構,並且可以查看視圖的執行效率(視圖上的小圓點,綠色表示流暢,黃色和紅色次之),所以我們可以很方便的查看哪些view可能會影響我們的性能從而去進一步優化它。
2.ViewStub標簽
此標簽可以使UI在特殊情況下,直觀效果類似於設置View的不可見性,但是其更大的意義在於被這個標簽所包裹的Views在默認狀態下不會占用任何內存空間。
3.include標簽
可以通過這個標簽直接加載外部的xml到當前結構中,是復用UI資源的常用標簽。
4.merge標簽
它在優化UI結構時起到很重要的作用。目的是通過刪減多余或者額外的層級,從而優化整個Android Layout的結構。
5.布局用Java代碼比寫在XML中快
一般情況下對於Android程序布局往往使用XML文件來編寫,這樣可以提高開發效率,但是考慮到代碼的安全性以及執行效率,可以通過Java代碼執行創建,雖然Android編譯過的XML是二進制的,但是加載XML解析器的效率對於資源占用還是比較大的,Java處理效率比XML快得多,但是對於一個復雜界面的編寫,可能需要一些套嵌考慮,如果你思維靈活的話,使用Java代碼來布局你的Android應用程序是一個更好的方法。
3、重用系統資源:
1. 利用系統定義的id
在xml文件中引用系統的id,只需要加上“@android:”前綴即可。如果是在Java代碼中使用系統資源,和使用自己的資源基本上是一樣的。不同的是,需要使用android.R類來使用系統的資源,而不是使用應用程序指定的R類。
2. 利用系統的圖片資源
這樣做的好處,一個是美工不需要重復的做一份已有的圖片了,可以節約不少工時;另一個是能保證我們的應用程序的風格與系統一致。
3. 利用系統的字符串資源
如果使用系統的字符串,默認就已經支持多語言環境了。比如直接使用了@android:string/yes和@android:string/no,在簡體中文環境下會顯示“確定”和“取消”,在英文環境下會顯示“OK”和“Cancel”。
4. 利用系統的Style
假設布局文件中有一個TextView,用來顯示窗口的標題,使用中等大小字體。可以使用下面的代碼片段來定義TextView的Style。
第7節 TableLayoutTableLayout顧名思義,就是像表格一樣的布局。它是LinearLayout的子類,所以擁有TableLayout的所有屬性。7.1
一、前言今天是元旦,也是Single Dog的嚎叫之日,只能寫博客來祛除寂寞了,今天我們繼續來看一下Android中的簽名機制的姊妹篇:Android中是如何驗證一個Ap
本文實例為大家分享了Android ImageLoader框架的使用方法,供大家參考,具體內容如下1.准備工作1)導入universal-image-loader-1.9
本文以實例形式講述了Android Touch事件分發過程,對於深入理解與掌握Android程序設計有很大的幫助作用。具體分析如下:首先,從一個簡單示例入手:先看一個示例