第5章 Android進(jìn)程/線程和程序內(nèi)存優(yōu)化
5.1 Android 進(jìn)程和線程
進(jìn)程(Process)是程序的一個(gè)運(yùn)行實(shí)例,以區(qū)別于“程序”這一靜態(tài)的概念
而線程(Thread)則是CPU調(diào)度的基本單位。
實(shí)驗(yàn)1 創(chuàng)建Activity
結(jié)論:?jiǎn)?dòng)了3個(gè)線程:mainThread 和 2個(gè)Binder Thread
實(shí)驗(yàn)2 創(chuàng)建Service
結(jié)論:Service也是寄存于 ActivityThread 中;啟動(dòng)Service,同樣需要兩個(gè)Binder線程
實(shí)驗(yàn)3 創(chuàng)建多個(gè)Activity(Service)
結(jié)論:主線程mainThread只有一個(gè);Binder線程數(shù)量有所變化
實(shí)驗(yàn)4 不同組件(除非特別聲明)運(yùn)行在同一個(gè)進(jìn)程中(并且均由主線程處理事件)
如果兩個(gè)對(duì)象處于同一進(jìn)程空間中,那么內(nèi)存區(qū)域應(yīng)該是可共享訪問的。
小結(jié):
四大組件不是程序(進(jìn)程)的全部,而只是它的“零件”
應(yīng)用程序啟動(dòng)后,將創(chuàng)建ActivityThread主線程
同一個(gè)包中的組件將運(yùn)行在相同的進(jìn)程空間中
不同包中的組件可以通過一定的方式運(yùn)行在一個(gè)進(jìn)程空間中
一個(gè)Activity應(yīng)用啟動(dòng)后至少會(huì)有3個(gè)線程:即1個(gè)主線程和2個(gè)Binder線程
5.2 Handler, MessageQueue, Runnable 與 Looper

Looper不斷獲取MessageQueue中的一個(gè)Message,然后由Handler來處理。

Thread和Handler是一對(duì)多的關(guān)系。

5.3 UI主線程——ActivityThread
ActivityThread是Activity所屬的線程,也就是UI主線程(自己理解:ActivityThread不是線程類,是管理主線程的類):
public static void main(String[] args) {
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();//主Handler
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
消息是推動(dòng)整個(gè)系統(tǒng)動(dòng)起來的基礎(chǔ)。

5.4 Thread類
5.4.1 Thread的內(nèi)部原理
Thread實(shí)現(xiàn)了Runnable, 也就是線程是“可執(zhí)行的代碼”
使用Thread的方法:
1、繼承Thread,重寫它的run方法,然后調(diào)用:
MyThread thr = new MyThread(...);
thr.start();
2、直接實(shí)現(xiàn)Runnable
new Thread(Runnble target).start();
5.4.2 Thread 休眠和喚醒
- wait 和 notify/notifyAll
wait的解釋
Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object.
- interrupt
wait是一種自愿行為,interrupt則是被迫的,如字面意思一樣,中斷線程的執(zhí)行過程
- join
t1.start();
t1.join();
t2.start();
join的目的 只有當(dāng)t1線程執(zhí)行完成時(shí),才執(zhí)行后面的t2.start(),保證兩個(gè)線程的順序執(zhí)行
- sleep
和wait一樣是自愿的行為,wait是等待某個(gè)object,sleep是等待時(shí)間。

5.5 Android應(yīng)用程序如何利用CPU的多核處理能力
如何主動(dòng)利用CPU的多核能力,提高自身的應(yīng)用程序的性能?
答案是 針對(duì)Java-Based的并行編程技術(shù)
方式1:使用Java線程
方式2:使用AsyncTask
方式3:使用IntentService
5.6 Android應(yīng)用程序的典型啟動(dòng)流程

舊的Activity先onPause(),新的Activity再onResume()
5.7 Activity程序的內(nèi)存管理與優(yōu)化
5.7.1 系統(tǒng)對(duì)內(nèi)存使用的限制
查看某個(gè)進(jìn)程中的內(nèi)存使用情況用 dumpsys命令,
dumpsys meminfo xxxPkg(或者pid)
Heap區(qū)域分Native(本地代碼的情況)、Dalvik(虛擬機(jī)中的堆分配)
5.7.2 Android中的內(nèi)存泄漏和內(nèi)存檢測(cè)
工具:Logcat、Memory Monitor、Heap Viewer、Allocation Tracker
定位問題的典型流程:用Memory Monitor觀察程序是否經(jīng)常性發(fā)生GC(問題是否存在)—— 答案如果是肯定的,進(jìn)一步用Heap Viewer來甄別可疑的對(duì)象類型(導(dǎo)致問題的可疑對(duì)象是什么) —— 最后借助于Allocation Tracker來確定發(fā)生問題的代碼在哪個(gè)位置(問題是如何產(chǎn)生的)
自己理解:現(xiàn)在Android Studio的Profile工具集成上面三步
內(nèi)存泄漏檢測(cè)工具:Memory Analyzer Tool(MAT),用其Memory Leak Report