- 多進程
安卓支持多進程
好處:
-- 減輕APP內(nèi)存壓力肠槽;
-- 邏輯相對獨立倘要;例如我們可以使Service在獨立進程中執(zhí)行數(shù)據(jù)計算處理操作菇爪,
處理的結(jié)果與主進程通過AIDL通信;
缺點:
-- 首次進入新啟動進程的頁面時會有延時的現(xiàn)象忠怖,如閃屏,一般與Activity 的主題有關(guān)元莫;
-- Application 被實例化多次呜师,應(yīng)考慮其中定義的一些參數(shù)是否合理;
可以在Application中加進程的邏輯判斷双炕,在指定的進程中狞悲,才初始化對應(yīng)的數(shù)據(jù);
-- 多進程間通過 SharedPreferences 共享數(shù)據(jù)時不穩(wěn)定妇斤;
-- APP退出操作不能完全退出摇锋,僅退出了當(dāng)前進程;
- 線程的管理
單個線程的創(chuàng)建站超,比較簡單荸恕,通用的方法是:實現(xiàn)Runnable接口或者繼承Thread類。
但是死相,這種方式創(chuàng)建的線程融求,不應(yīng)該任意使用,應(yīng)對創(chuàng)建的線程做好管理算撮,
例如:線程緩存生宛、順序執(zhí)行县昂、最大并發(fā)數(shù)等等;
Java提供的一套線程管理的方案:線程池(ThreadPoolExecutor)陷舅,
關(guān)于線程池的使用倒彰,Java默認(rèn)給封裝了幾個類型,都可以通過Executors直接創(chuàng)建蔑赘,例如:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
線程池類型:
FixedThreadPool:固定大小的線程池狸驳,可解決最大并發(fā)數(shù);
SingleThreadPool:單一線程池缩赛,可保證線程一個個執(zhí)行耙箍;
CachedThreadPool:緩存線程池,減少了線程的重用性酥馍,提高了性能辩昆;
ScheduledThreadPool:定時線程池,可定時旨袒、延時執(zhí)行線程汁针;
具體的使用,我們需要根據(jù)特定場合砚尽,如果使用不當(dāng)施无,也會有一些問題:
FixedThreadPool 和 SingleThreadPool :
允許的請求隊列長度過大,可能會堆積大量的請求必孤,從而導(dǎo)致 OOM猾骡;
CachedThreadPool 和 ScheduledThreadPool :
允許的創(chuàng)建線程數(shù)量過大,可能會創(chuàng)建大量的線程敷搪,從而導(dǎo)致 OOM兴想。
其實,我們還可以通過new ThreadPoolExecutor()赡勘,構(gòu)建自定義的線程池嫂便,自己定義的規(guī)則,
如何管控線程闸与,自己也清楚毙替,如下:
int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();//最大可用的處理器數(shù)量
int KEEP_ALIVE_TIME = 1;// 設(shè)置線程存活時間(setKeepAliveTime),確奔#空閑時線程能被釋放
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();//線程隊列厂画,存放線程
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,NUMBER_OF_CORES*2,
KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT,taskQueue, new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());
Android中和線程、線程池相關(guān)的還有IntentService映胁、AsyncTask木羹、SurfaceView等甲雅,此處不再累述解孙;
- 線程使用
子線程中不能直接更新界面坑填,更新界面必須在UI線程中進行。
線程間通信Handler弛姜,可以自定義接口回調(diào)脐瑰,也可使用EventBus等代替,
各有優(yōu)缺點廷臼,自己根據(jù)情況合理使用苍在。
注意:Handler不要通過 Msg 傳遞大的對象,會導(dǎo)致內(nèi)存問題荠商。
- 線程鎖
作用:確保數(shù)據(jù)同步執(zhí)行寂恬,保證數(shù)據(jù)的原子性。
線程鎖類型莱没,按使用方式可分為:可重入鎖初肉、不可重入鎖(自旋鎖)、公平鎖饰躲、非公平鎖牙咏、讀寫鎖。
顯示鎖用Lock來定義嘹裂、內(nèi)置鎖用syschronized
Lock接口妄壶,主要定義方法:
lock();
unLock();
tryLock();
lockInterrupt();
newCondition();
可重入鎖(已獲得某對象、代碼庫的鎖后寄狼,可直接訪問它的其他同步方法):
syschronized丁寄、reentraintLock
-- synchronized編碼較簡單;
-- ReentrantLock功能更豐富一些例嘱,如時間鎖等候狡逢,可中斷鎖等候,鎖投票等拼卵,還可以定義多個條件奢浑;
-- ReentrantLock必須在finally中釋放鎖;
-- ReentrantLock 的性能比synchronized會好點腋腮;
自旋鎖(自旋鎖可以使線程在沒有取得鎖的時候雀彼,不被掛起,而轉(zhuǎn)去執(zhí)行一個空循環(huán)即寡,
(即所謂的自旋徊哑,就是自己執(zhí)行空循環(huán)),若在若干個空循環(huán)后聪富,線程如果可以獲得鎖莺丑,則繼續(xù)執(zhí)行。)
公平鎖(排隊競爭)
-- 構(gòu)造ReentrantLock (true)時,表示為公平鎖梢莽;
非公平鎖(非排隊競爭)
-- 構(gòu)造ReentrantLock ()時萧豆,表示為非公平鎖;
讀寫鎖
允許多個讀操作同時進行昏名,但每次只允許一個寫操作涮雷。
讀寫鎖是一種性能優(yōu)化的策略。
--ReentrantReadWriteLock
- 進程使用
-- 官方不推薦 在多 進 程 之 間 用 SharedPreferences 共 享數(shù) 據(jù) ;
-- 盡量減少不同 APP 之間的進程間通信及拉起行為轻局。拉起導(dǎo)致占用系統(tǒng)資源洪鸭,影響用戶體驗。
- 進程間通信時注意URI傳遞
7.0之后仑扑,安卓安全性提高览爵,APP之間傳遞文件路徑時,應(yīng)注意適配镇饮,
防止出現(xiàn)FileUriExposedException異常拾枣;
具體請參考:
http://www.reibang.com/p/bec4497c2a63
7.帶返回值的異步任務(wù)Callable<T>
其實,除Runnable接口外盒让,Callable泛型參數(shù)化接口也可以實現(xiàn)異步任務(wù)梅肤。
Runnable與Callable不同點:
1. Runnable不返回任務(wù)執(zhí)行結(jié)果,Callable可返回任務(wù)執(zhí)行結(jié)果邑茄;
2. Callable在任務(wù)無法計算結(jié)果時拋出異常姨蝴,而Runnable不能;
3. Runnable任務(wù)可直接由Thread的start方法或ExecutorService的submit方法去執(zhí)行肺缕;
Callable只通過ExecutorService的submit方法去執(zhí)行左医;
ExecutorService的submit方法返回FutureTask對象,要獲得Callable接口返回的執(zhí)行結(jié)果同木,
需要調(diào)用FutureTask.get()方法實現(xiàn)浮梢,此方法會阻塞主線程直到獲取‘將來’結(jié)果;
當(dāng)不調(diào)用此方法時彤路,主線程不會阻塞秕硝!
Callable示例:查找文件包含某關(guān)鍵字總個數(shù):每個文件啟動一個線程查找關(guān)鍵字
public class FileSearchTask {
public static void main(String[] args) throws ExecutionException,
InterruptedException {
String path = args[0];
String keyword = args[1];
int c = 0;
File[] files = new File(path).listFiles();
ArrayList<Future<Integer>> rs = new ArrayList<>();
for(File file: files){ //每個文件啟動一個task去查找
MatchCount count = new MatchCount();
count.file = file;
count.keyword = keyword;
FutureTask<Integer> task = new FutureTask(count);
rs.add(task); //將任務(wù)返回的結(jié)果添加到集合中
Thread thread = new Thread(task);
thread.start();
}
for(Future<Integer> f: rs){
c += f.get(); //迭代返回結(jié)果并累加,會阻塞線程洲尊,直到結(jié)果返回远豺;
}
System.out.println("包含關(guān)鍵字的總文件數(shù)為:" + c);
}
}
class MatchCount implements Callable<Integer>{
public File file;
public String keyword;
private Integer count = 0;
public Integer call() throws Exception { //call封裝線程所需做的任務(wù)
if(search(file))
count ++;
return count;
}
public boolean search(File file){
boolean founded = false;
try(Scanner scanner = new Scanner(new FileInputStream(file))){
while(!founded && scanner.hasNextLine()){
if (scanner.nextLine().contains(keyword))
founded = true;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return founded;
}
}
第一篇: 安卓編程技巧總結(jié)(1) 資源與UI布局處理
http://www.reibang.com/p/ff97b15d5c9d
第二篇: 安卓編程技巧總結(jié)(2) 基礎(chǔ)組件開發(fā)
http://www.reibang.com/p/b05752377887
第三篇:安卓編程技巧總結(jié)(3) 進程與線程處理
http://www.reibang.com/p/7d05c8a368bd
第四篇:安卓編程技巧總結(jié)(4) 數(shù)據(jù)文件處理
http://www.reibang.com/p/0515df3b697d
第五篇:安卓編程技巧總結(jié)(5) 圖片處理
http://www.reibang.com/p/76690b2ba310
第六篇:安卓編程技巧總結(jié)(6) APP安全分析
http://www.reibang.com/p/4347ff392122