編輯:關於Android編程
本文是針對Android的App開發優化(一)
應用程序內部廣播通信,優先采用LocalBroadcastManager,安全性更好,運行效率更高。
優勢:平時常說BroadcastReceiver,采用的是Binder通信方式,這是跨進程的通信方式,系統資源消耗固然更多。而廣播LocalBroadcastManager,采用的是Handler通信機制,Handler的實現是應用內的通信方式,所以效率與安全性都更高。
用法:
(1) 創建廣播接收者
//廣播類型
public static final String ACTION_SEND = "1";
//自定義廣播接收者
public class AppBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//TODO
}
}
//創建廣播接收者
AppBroadcastReceiver appReceiver = new AppBroadcastReceiver();
(2) 注冊廣播
LocalBroadcastManager.getInstance(context).registerReceiver(appReceiver, new IntentFilter(ACTION_SEND));
注:LocalBroadcastManager注冊廣播只能通過代碼注冊的方式,而不能通過xml中靜態配置,本地廣播並沒有走系統廣播的流程。
(3) 發送廣播
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(ACTION_SEND));
(4) 取消廣播
LocalBroadcastManager.getInstance(context).unregisterReceiver(appReceiver);
線程創建優先采用線程池ThreadPoolExecutor
,而不是new Thread()
; 另外設置線程優先級為後台運行優先級,能有效減少Runnable創建的線程和和UI線程之間的資源競爭。
優勢: 通過new Thread()
來創建線程是比較常用的方式,而使用線程池的方式有不少優勢如下
用法:
//創建Runable對象
Runnable runnable = new Runnable() {
@Override
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
//TODO
}
};
//創建線程池
ExecutorService threadPoolExecutor = new ThreadPoolExecutor(
corePoolSize, maximumPoolSize,
keepAliveTime, unit, workQueue);
//執行runnable
threadPoolExecutor.execute(runnable);
對於corePoolSize,一般往往可以設置為Runtime.getRuntime().availableProcessors()
,代表當前系統活躍的CPU個數。
另外系統采用工廠模式,通過設置ThreadPoolExecutor的不同參數,提供四種默認線程池: (1) newCachedThreadPool 可緩存線程池,若線程空閒60s則回收,若無空閒線程可無限創建新線程,定義如下: new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
調用方法:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
cachedThreadPool.execute(runnable);
(2) newFixedThreadPool 定長線程,固定線程池大小,定義如下: new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
調用方法:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(nThreads);
fixedThreadPool.execute(runnable);
(3) newSingleThreadExecutor 只有一個線程的線程池,定義如下: new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));
調用方法:
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
newSingleThreadExecutor.execute(runnable);
(4) newScheduledThreadPool 可定時周期執行的線程池,定義如下: new ThreadPoolExecutor(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
調用方法:
ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(corePoolSize);
scheduledThreadPool.schedule(runnable, delay, TimeUnit.SECONDS);
ArrayList基於動態數組的數據結構, 對於隨機訪問(get/set),ArrayList效率比LinkedList高; LinkedList基於鏈表的數據結構,對於新增和刪除(add/remove),LinedList效率比ArrayList高;
(1)對於list, 優先選擇ArrayList,除非少數需要大量的插入/刪除操作才使用LinkedList。因為當數據量非常大時get操作,LinkedList時間復雜度為o(n), 而ArrayList時間復雜度為o(1)。
(2)循環遍歷
LinkedList采用foreach方式, 效率最高。for循環方式效率大幅度降低。
List<Integer> list = new LinkedList<Integer>();
for (Integer j : list) {
... //TODO
}
ArrayList采用for循環+臨時變量保存size,效率最高。 foreach方式效率略微降低。
List<Integer> list = new ArrayList<Integer>();
int len = list.size();
for (int j = 0; j < len; j++) {
list.get(j);
}
(3)采用new ArrayList()方式,初始大小為0,首次增加數組時,擴充大小到12,以後到數組需要增長時,會將大小增加50%,並將原來的成員全部復制到新的數組內。所以盡可能將ArrayList提前設置成目標大小,或者接近目標大小,以減少數組不斷創建與復制的過程,提高效率。
(1)同時需要key和value,采用如下遍歷方法:
Map<String, String> map = new HashMap<String, String>();
for (Map.Entry<String, String> entry : map.entrySet()) {
entry.getKey();
entry.getValue();
}
(2)只需要獲取key,采用如下遍歷方法:
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
// key process
}
(3) 當HashMap的key是整型時,采用SparseArray,效率更高。避免了對key與value的自動裝箱與解箱操作。
內存對象,通過對象池技術來達到重復利用,減少對象重復創建。,從而減少內存分配和回收。
使用Job Scheduler,應用需要做的事情就是判斷哪些任務是不緊急的,可以交給Job Scheduler來處理,Job Scheduler集中處理收到的任務,選擇合適的時間,合適的網絡,再一起進行執行。
Enum比靜態常量,至少需要多過於2倍以上的內存空間,應該在Android中避免使用枚舉。
由於onDraw方法調用比較頻繁,需避免對象創建操作,因為迅速增加內存,同樣引起頻繁的gc,甚至內存抖動。
項目中常用到的圓形進度條有好多個,從網上搜到的自定義進度條多是封裝的比較好的代碼,但是不利於初學者,現在本博客就教給大家如何一步步實現自定義進度條的效果 相關視頻鏈接:
從實際使用需要出發,以最簡單的方式實現了幾種類型的MD狀態欄。(重點在fitsSystemWindows的使用)0,使用前提Theme.AppCompat.Light.D
適配器模式的定義是:將一個類的接口,轉換成客戶期望的另一個接口,適配器讓原本接口不兼容的類可以作無間。看下以下兩張圖就更清楚了 適配器可以實現接口的解耦,如果過一段時
前面說了文件操作和主界面,接下來說說文件的過濾和排序,我們都知道在我們的設備裡,不管是PC還是手機,總有一些我們 看不到的文件夾,那就是所謂的隱藏文件,大部分的隱藏文件,
今天主要分析下ActivityManagerService(服務端) 與