一、進程與線程區(qū)別
-
進程:系統(tǒng)進行資源分配和調度的基本單位描融,進程是線程的容器
-
進程的生命周期:
- 前臺進程
- 可見進程
- 服務進程
- 后臺進程
- 空進程
-
-
線程:CPU調度的最小單位待牵。線程是進程中可獨立執(zhí)行的最小單位馒过,也是 CPU 資源(時間片)調度的基本單位坚俗。同一個進程中的線程可以共享進程中的資源,如內存空間和文件句柄
-
線程的生命周期
- 新建:當程序使用new關鍵字創(chuàng)建了一個線程之后尸昧,該線程就處于新建狀態(tài)揩页,此時僅由JVM為其分配內存,并初始化其成員變量的值
- 就緒:當線程對象調用了start()方法之后烹俗,該線程處于就緒狀態(tài)爆侣。JVM會為其創(chuàng)建方法調用棧和程序計數(shù)器,等待調度運行
- 運行:如果處于就緒狀態(tài)的線程獲得了CPU衷蜓,開始執(zhí)行run()方法的線程執(zhí)行體累提,則該線程處于運行狀態(tài)
- 阻塞 : 當處于運行狀態(tài)的線程失去所占用資源之后,便進入阻塞狀態(tài)
-
死亡:線程會以如下3種方式結束磁浇,結束后就處于死亡狀態(tài):
- ① run()或call()方法執(zhí)行完成斋陪,線程正常結束。
- ② 線程拋出一個未捕獲的Exception或Error。
- ③ 直接調用該線程stop()方法來結束該線程——該方法容易導致死鎖无虚,通常不推薦使用
-
二缔赠、開啟多進程方法
1、Android中的多進程模式:
- 在Android中多進程是指一個應用中存在多個進程的情況,實現(xiàn)方法就是給四大組件在AndroidManifest中指定android:process屬性友题。
- android:process=":remote"代表當前的完整包名加上:remote進程嗤堰,
":"開頭的進程屬于當前應用的私有進程,其他的應用組件不可以和它跑在同一個進程中.
而進程名不以冒號開頭的進程(android:process="com.ryg.chapter_2.remote"),屬于全局進程,其他應用通過ShareUID方式可以和它跑在同一個進程中。 - 不同進程的組件會擁有獨立的虛擬機度宦,Application以及內存空間
2踢匣、實現(xiàn)跨進程的通信方式:
Intent來傳遞數(shù)據(jù)
共享文件和SharedPreferences
基于Binder的Messenger和AIDL以及Socket等
三、IPC基礎概念介紹
序列化:序列化就是一種用來處理對象流的機制戈抄,所謂對象流也就是將對象的內容進行流化离唬,Serializable和Parcelable接口可以完成對象的序列化的過程,當我們需要通過Intent和Binder傳輸數(shù)據(jù)的時候,就需要進行序列化。
-
序列化方式:
-
實現(xiàn)Serializable接口(空實現(xiàn)划鸽,標志接口):
需要一個類實現(xiàn)Serializable接口,并聲明一個serialVersionUID(不是必須的,它是用來反序列化的,序列化的時候系統(tǒng)會把當前類的serialVersionUID寫入序列化的文件中,當反序列化的時候,系統(tǒng)回去檢測文件中的serialVersionUID,如果一致,則可以實現(xiàn)反序列化,否則不能實現(xiàn)反序列化)输莺。
-
序列化:(將文字寫入文件)
User user = new User(0,"jake",true); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStrean("cache.txt"); out.writeObject(user); out.close();
-
反序列化(讀出文件)
ObjectInputStream in = new ObjectInputStream(new FileOInputStrean("cache.txt"); User newUser = (User)in.readObject(); out.close();
靜態(tài)成員變量屬于類,而不屬于對象裸诽,所以不會參加序列化的過程嫂用。并且使用了transient標記的成員變量也不會參與序列化。
-
-
實現(xiàn)Parcelable接口:需要一個類實現(xiàn)Parcelable接口,并生成一些方法
- 序列化功能是由writeToParcel方法來完成的,最終通過Parcel中的一系列write方法來完成的丈冬。
- 反序列化的功能是由CREATOR來完成的,其內容標明了如何創(chuàng)建序列化對象和數(shù)組,并通過Parcel的一系列read方法來完成反序列化的過程嘱函。
- 內容描述是通過describeContents來完成的。
-
Serializable和Parcelable接口的區(qū)別
- Serializable是Java的序列化接口,使用起來開銷很大,因為其序列化過程和反序列化的過程需要大量的IO操作殷蛇。
- Parcelable是Android提供的一個序列化方式,缺點就是有點麻煩实夹,但是可以通過插件生成橄浓。并且其效率高,主要用在內存的序列化上粒梦。
-
Binder(從Framework的角度來說,Binder是ServiceManager連接各種(ActivityManager,WindowManager等)和ManagerSerice的橋梁
- 在Android中,Binder主要用在Service,包括AIDL和Messager.在項目中創(chuàng)建一個aidl文件,其核心是其生成的Java文件的內部Stub和Stub的內部代理類Proxy,系統(tǒng)會默認生成一個這樣的java文件(這個類主要分為兩部分,首先它本身是一個Binder的接口(繼承了IInterface,所有在Binder中傳輸?shù)慕涌诙夹枰^承自IInterface的接口),其次它的內部是Stub類荸实。
- Binder中有兩個比較重要的方法(linkToDeath和unlinkToDeath),Binder運行在服務端進程,如果服務端進程由于某種原因異常終止,這個時候我們到服務端的Binder鏈接斷裂(稱為Binder死亡),會導致我們的遠程調用失敗匀们,客戶端的功能就會收到影響。linkToDeath是一個Binder死亡代理,當Binder死亡的時候,就會收到通知,從而解決上面的問題准给。
四泄朴、Android中的IPC方式
1、Bundle(只支持Bundle支持的數(shù)據(jù)類型露氮,適用于四大組件的通信)
- 實現(xiàn)了Parcelable接口,所以這個可以在不同的進程間傳輸,可以在Bundle中附加我們需要傳輸給遠程進程的信息并通過Intent發(fā)送出去祖灰。
2、使用文件共享(不適合高并發(fā)畔规,讀寫需要上鎖)
- A進程把數(shù)據(jù)寫入文件局扶,B進程通過讀取這個文件來獲取數(shù)據(jù)。但是并發(fā)的讀/寫會造成較大的問題。
- SharePreference:是Android提供的輕量級存儲方案,本質是xml文件三妈,通過鍵值對形式存儲數(shù)據(jù)畜埋。但是不建議在進程之間通信的時候使用SharePreference,其對于讀/寫有一定的緩存策略(內存中會有一份SharePrefernce的緩存)畴蒲,很大幾率會造成數(shù)據(jù)丟失
3悠鞍、使用Messenger(串行通信,不支持高并發(fā))
- 信使,底層實現(xiàn)方案是AIDL模燥。在Messager中進行數(shù)據(jù)傳遞必須將數(shù)據(jù)放入Message中新建一個Handler,拿到message后做相關操作咖祭。Messager是以串行的方式來處理的,不適合并發(fā).
4、使用AIDL(使用比較復雜蔫骂,但是功能強大)
- 支持的數(shù)據(jù)類型有基本數(shù)據(jù)類型心肪,String,CharSequence,ArrayList,HashMap,Parcelable對象
- 注意不要在onServiceConnectioned和onServiceDisconnected中進行耗時的操作。
5纠吴、使用ContentProvider(主要用于CURD)
- 底層的實現(xiàn)是Binder.自定義Provider就是繼承自Provider,并實現(xiàn)其中的onCreate(運行在主線程),query硬鞍,getType,insert,delete,update等方法(運行在Binder線程池中),其增刪改查是多線程并發(fā)進行的,在運用的時候需要做到多線程同步問題。
6戴已、Socket:(主要用于網(wǎng)絡傳輸)
- 套接字固该,不僅能實現(xiàn)進程間通信,還能實現(xiàn)設備間通信糖儡。
- 流式套接字TCP:面向連接伐坏,提供穩(wěn)定的雙向通信功能,連接的建立需要經(jīng)過3次握手握联,畫質清晰
- 用戶數(shù)據(jù)報套接字UDP:面向無連接桦沉,提供不穩(wěn)定的單項功能。具有更好的效率金闽,但是不能保證數(shù)據(jù)的正確性纯露,流暢