天天看點

Android開發進階進階——多程序間通信一. 什麼是多程序?二. 程序的等級三. 多程序的建立四. 多程序間的通信IPC五.序列化插件

多程序就是多個程序的意思,那麼什麼是程序呢?

當一個應用在開始運作時,系統會為它建立一個程序,一個應用預設隻有一個程序,這個程序(主程序)的名稱就是應用的包名。

程序的特點:

程序是系統資源和配置設定的基本機關,而線程是排程的基本機關。

每個程序都有自己獨立的資源和記憶體空間

其它程序不能任意通路目前程序的記憶體和資源

系統給每個程序配置設定的記憶體會有限制

根據上邊的引言和程序的特點可以看出,使用多程序的場景為:需要使apk所使用的記憶體限制擴大。

按優先級可以分為五類,優先級從高到低排列:

Android開發進階進階——多程式間通信一. 什麼是多程式?二. 程式的等級三. 多程式的建立四. 多程式間的通信IPC五.序列化插件

Android程序分類

前台程序:該程序包含正在與使用者進行互動的界面元件,比如一個Activity。在接收關鍵生命周期方法時會讓一個程序臨時提升為前台程序,包括任何服務的生命周期方法onCreate()和onDestroy()和任何廣播接收器onReceive()方法。這樣做確定了這些元件的操作是有效的原子操作,每個元件都能執行完成而不被殺掉。

可見程序:該程序中的元件雖然沒有和使用者互動,但是仍然可以被看到。activity可見的時候不一定在前台。一個簡單的例子是前台的 activity 使用對話框啟動了一個新的 activity 或者一個透明 activity 。另一個例子是當調用運作時權限對話框時(事實上它就是一個 activity!)。

服務程序:該程序包含在執行背景操作的服務元件,比如播放音樂的Service。對于許多在背景做處理(如加載資料)而沒有立即成為前台服務的應用都屬于這種情況。

請特别注意從onStartCommand()傳回的常量,如果服務由于記憶體壓力被殺掉,它表示控制什麼發生什麼:

START_STICKY表示希望系統可用的時候自動重新開機服務,但不關心是否能獲得最後一次的 Intent (例如,可以重建自己的狀态或者控制自己的 start/stop 生命周期)。

START_REDELIVER_INTENT是為那些在被殺死之後重新開機時重新獲得 Intent 的服務的,直到用傳遞給 onStartCommand() 方法的 startId 參數調用stopSelf()為止。這裡會使用 Intent 和 startId 作為隊列完成工作。

START_NOT_STICKY用于那些殺掉也沒關系的服務。這适合那些管理周期性任務的服務,它們隻是等待下一個時間視窗工作。

背景程序:該程序包含的元件沒有與使用者互動,使用者也看不到 Service。在一般操作場景下,裝置上的許多記憶體就是用在這上面的,使可以重新回到之前打開過的某個 activity 。

空程序:沒有任何界面元件、服務元件,或觸發器元件,隻是出于緩存的目的而被保留(為了更加有效地使用記憶體而不是完全釋放掉),隻要 Android 需要可以随時殺掉它們。

Android多程序建立很簡單,隻需要在AndroidManifest.xml的聲明四大元件的标簽中增加”android:process”屬性即可。命名之後,就成了一個單獨的程序。

process分私有程序和全局程序:

私有程序的名稱前面有冒号,例如:

全局程序的名稱前面沒有冒号,例如:

為了節省系統記憶體,在退出該Activity的時候可以将其殺掉(如果沒有人為殺掉該程序,在程式完全退出時該程序會被系統殺掉)。

多程序被建立好了,應用運作時就會對程序進行初始化,如果一個application中有多個程序,在進行全局初始化時,多程序會被初始化多次。

解決辦法:判斷目前程序,然後做相應的初始化操作。

IPC:InterProcess Communication,即程序間通信。

我們知道,同一個程序的多個線程是共享該程序的所有資源,但多個程序間記憶體是不可見的,也就是說多個程序間記憶體是不共享的。那麼程序間是如何進行通信的呢?

Android中提供了三種方法:

系統實作。

AIDL(Android Interface Definition Language,Android接口定義語言):大部分應用程式不應該使用AIDL去建立一個綁定服務,因為它需要多線程能力,并可能導緻一個更複雜的實作。

Messenger:利用Handler實作。(适用于多程序、單線程,不需要考慮線程安全),其底層基于AIDL。

如需讓服務與遠端程序通信,則可使用Messenger為服務提供接口。

定義一個MessengerService繼承自Service,并在AndroidManifest.xml中聲明并給一個程序名,使該服務成為一個單獨的程序。代碼如下:

MessengerService.java

AndroidManifest.xml檔案的配置如下:

MessengerActivity.java

通過以上代碼,可以看到Messenger的使用方法:

服務實作一個Handler,由其接收來自用戶端的每個調用的回調。

Handler用于建立Messenger對象(對Handler的引用)。

Messenger建立一個IBinder,服務通過onBind()使其傳回用戶端。

用戶端使用IBinder将Messenger(引用服務的Handler)執行個體化,然後使用後者将Message對象發送給服務。

服務在其Handler中(具體地講,是在handleMessage()方法中)接收每個Message。

這樣,用戶端并沒有調用服務的“方法”。而用戶端傳遞的“消息”(Message對象)是服務在其Handler中接收的。

以上代碼實作的應用,剛打開會彈出一個binding,binding表示打開應用Activity就通過Messenger連接配接了一個服務程序,然後點選say hello會彈出hello,trampcr,這表示了Activity通過Messenger将Message發送給了服務程序。如下圖:

Android開發進階進階——多程式間通信一. 什麼是多程式?二. 程式的等級三. 多程式的建立四. 多程式間的通信IPC五.序列化插件

MessengerService程序與MessengerActivity之間的通信

AIDL是一種接口描述語言,通常用于程序間通信。

使用AIDL的步驟:

建立AIDL,在main下建立一個檔案夾aidl,然後在aidl下建立AIDL檔案,這時系統會自動為該檔案建立一個包名。

aidl檔案中會有一個預設的basicType方法,我們為它增加一個getName方法。代碼如下:

以上是我們自己建立的aidl檔案,系統還會自動生成aidl代碼,所在位置為:build/generated/source/aidl下debug和release,但是此時debug下沒有任何東西,可以rebuild或運作一下程式,再次打開debug,發現生成了一個包和一個aidl檔案。

在java下建立一個類AIDLService繼承自Service。代碼如下:

在AndroidManifest.xml中注冊,并給一個程序名,是該服務成為一個獨立的程序。

在MainActivity中進行與AIDLService之間的程序間通信。代碼如下:

在Activity中利用bindService與AIDLService進行連接配接,通過IMyAidlInterface執行個體與AIDLService程序進行通信,如下圖所示:

Android開發進階進階——多程式間通信一. 什麼是多程式?二. 程式的等級三. 多程式的建立四. 多程式間的通信IPC五.序列化插件

AIDLService程序與MainActivity之間的通信.gif

Parcelable code generate:自動生成實作了Parcelable接口的對象。

    本文轉自 一點點征服   部落格園部落格,原文連結:http://www.cnblogs.com/ldq2016/p/8417692.html,如需轉載請自行聯系原作者

繼續閱讀