安卓進(jìn)程間通信(IPC)

前言

進(jìn)程間通信即IPC(Inter-Process Communication)。

安卓工程的manifest文件中可以指定各個(gè)組件運(yùn)行的進(jìn)程名(process)丽焊。

安卓的進(jìn)程間通信主要以service為基礎(chǔ),官方文檔

IPC有兩種方式浅蚪,使用Messenger和AIDL皮胡。

使用Messenger

Messenger是進(jìn)程間通信最簡單的實(shí)現(xiàn)方式,它在單一線程中處理所有消息請(qǐng)求拆檬,無須考慮線程安全問題洪己。 Messenger的基礎(chǔ)是Handler,使用步驟如下:

  1. 自定義一個(gè)Handler用于處理消息竟贯;

  2. 以自定義的Handler實(shí)例創(chuàng)建一個(gè)Messenger實(shí)例答捕, 在Service的IBinder onBind(Intent intent)方法返回該Messenger實(shí)例;

  3. 調(diào)用者bindService成功后屑那,在onServiceConnected(ComponentName className, IBinder service)中用Binder創(chuàng)建一個(gè)Messenger對(duì)象拱镐,Messenger messenger = new Messenger(service)艘款;

  4. 使用messenger對(duì)象發(fā)送消息對(duì)象Message,將消息交給自定義的Handler處理痢站,實(shí)現(xiàn)IPC

public class LocalService extends Service {

    private final IBinder mBinder = new LocalBinder();
    private final Random mGenerator = new Random();

    public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}

/** 客戶端使用 */
public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent(this, LocalService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
  
    public void onButtonClick(View v) {
        if (mBound) {
            int num = mService.getRandomNumber();
            Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

使用AIDL

使用步驟如下磷箕,

  1. 新建一個(gè)aidl文件如IRemoteInterface.aidl,定義需要的接口阵难,build之后會(huì)生成一個(gè)同名的IRemoteInterface.class文件;
  2. IRemoteInterface中有一個(gè)Stub接口岳枷,接口與我們定義的一致,在Service中實(shí)現(xiàn)該Stub接口呜叫,并在onBind中返回該實(shí)現(xiàn)類實(shí)例空繁;
  3. 客戶端綁定service成功后,
public void onServiceConnected(ComponentName className, IBinder service) {
    //可用這個(gè)訪問aidl中定義的接口
        IRemoteInterface mIRemoteService = IRemoteService.Stub.asInterface(service);
}

上面Stub.asInterface方法中朱庆,會(huì)返回一個(gè)Stub類的代理對(duì)象盛泡,所以后續(xù)客戶端的方法調(diào)用實(shí)際是交給代理對(duì)象執(zhí)行的。

參數(shù)方向說明

aidl的參數(shù)有in, out , inout三個(gè)方向類型娱颊。因?yàn)榭邕M(jìn)程無法直接訪問對(duì)象結(jié)構(gòu)傲诵,對(duì)象的傳遞是通過序列化,所以自定義類作為參數(shù)要實(shí)現(xiàn)Parcelable接口箱硕,也要在aidl中聲明拴竹。正確聲明參數(shù)方向可以減少不必要的序列化操作,提高效率剧罩。

in即輸入?yún)?shù)栓拜,在當(dāng)前進(jìn)程序列化,遠(yuǎn)程進(jìn)程反序列化后得到對(duì)應(yīng)的參數(shù)值惠昔。
out為輸出參數(shù)幕与,遠(yuǎn)程進(jìn)程方法執(zhí)行完成后結(jié)果如果需要回傳,則進(jìn)行序列化寫入镇防,客戶端進(jìn)程進(jìn)行反序列化得到結(jié)果啦鸣。
inout為輸入輸出參數(shù),同時(shí)具備上面兩個(gè)的特性营罢。

Messenger和AIDL的區(qū)別

Messenger和AIDL都用于進(jìn)程間通信赏陵,Messenger使用較為簡單,內(nèi)部是在單一線程中處理消息請(qǐng)求的饲漾,線程安全蝙搔。AIDL則不是線程安全的。根據(jù)實(shí)際需要考传,

如果您想讓服務(wù)同時(shí)處理多個(gè)請(qǐng)求吃型,則可直接使用 AIDL。 在此情況下僚楞,您的服務(wù)必須具備多線程處理能力勤晚,并采用線程安全式設(shè)計(jì)枉层。否則使用Messenger

End.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赐写,隨后出現(xiàn)的幾起案子鸟蜡,更是在濱河造成了極大的恐慌,老刑警劉巖揉忘,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異泣矛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)禾蚕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來换淆,“玉大人,你說我怎么就攤上這事倍试。” “怎么了易猫?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵具壮,是天一觀的道長。 經(jīng)常有香客問我棺妓,道長攘已,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任怜跑,我火速辦了婚禮样勃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘性芬。我一直安慰自己峡眶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布植锉。 她就那樣靜靜地躺著辫樱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俊庇。 梳的紋絲不亂的頭發(fā)上狮暑,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天鸡挠,我揣著相機(jī)與錄音,去河邊找鬼搬男。 笑死拣展,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缔逛。 我是一名探鬼主播备埃,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼译株!你這毒婦竟也來了瓜喇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤歉糜,失蹤者是張志新(化名)和其女友劉穎乘寒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匪补,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伞辛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夯缺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚤氏。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖踊兜,靈堂內(nèi)的尸體忽然破棺而出竿滨,到底是詐尸還是另有隱情,我是刑警寧澤捏境,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布于游,位于F島的核電站,受9級(jí)特大地震影響垫言,放射性物質(zhì)發(fā)生泄漏贰剥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一筷频、第九天 我趴在偏房一處隱蔽的房頂上張望蚌成。 院中可真熱鬧,春花似錦凛捏、人聲如沸担忧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涵妥。三九已至,卻和暖如春窒所,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吵取。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工皮官, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留实辑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓摄乒,卻偏偏與公主長得像残黑,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子梨水,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容