android進程間通信(AIDL的實現)

AIDL (Android Interface Definition Language)

近期做了一個進程間通信的需求,這里總結一下送挑。具體的需求是這樣的:

B應用在詳情頁需要調起A應用的播放功能柿祈,但播放地址是必須在播放器頁面再去獲取的哈误,但A應用不能調取B應用的請求,只能通過B應用中的請求拿到播放地址傳給A應用躏嚎,A然后進行播放蜜自。

  • 這里就需要用到進程間通信(icp:inter process communication:內部進程通信。)了卢佣。 業(yè)務邏輯大體如下:B在詳情頁點擊播放的時候通過普通的Intent或者scheme方式調起A應用對應的activity重荠,之后A應用會啟動B中定義的service,然后通過aidl的方法傳遞請求參數數據到B中虚茶,B拿到請求參數后起線程獲取播放地址戈鲁,然后回傳給A應用尾膊,A拿到播放地址后再進行播放。

流程圖如下(B應用就叫main應用荞彼,A應用就叫l(wèi)ite應用):

Paste_Image.png
  • 下面是具體實現:
    1.先在main應用中建立對應的aidl文件冈敛,
Paste_Image.png

這樣會在我們包名下建出aidl文件,這時鸣皂,我們需要在build下重新make project一下抓谴,這樣在build文件夾中就會生成對應的接口文件,如下圖:

Paste_Image.png

這樣寞缝,我們才能在代碼中引用這個接口癌压。

這時在IRemoteService.aidl文件中,還只是默認的方法荆陆,這里我們需要加上我們自己的方法滩届,這個文件其實就是一個接口文件,所以我們只能寫上方法的定義被啼,具體的實現還得再接口的實現中完成帜消。

在IRemoteService.aidl我們加上

/** 
 * @param couldId  視頻id 
 * @param callback  獲取playurl的回調 
 */String getPlayInfo(String couldId, LiteappCallback callback);

注意:上面方法中的參數LIteappCallback是又lite中需要傳給main的回調類,我們需要再次建一個aidl文件浓体,就叫LiteappCallback.aidl,代碼如下:

// LiteappCallback.aidlpackage 
com.main.mainapplication;
// Declare any non-default types here with import statements

interface LiteappCallback {    
 /**     
* Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     
*/    
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); 
//獲取url成功   
void getPlayUrlSuccess(String playUrl);    
//獲取url失敗
void getPlayUrlFail(String message);
}

其中兩個方法的具體實現在需要在lite應用中做的泡挺。
---別忘了添加aidl之后需要make project一下,否則你會發(fā)現在IRemoteService中用不了命浴。這里還需要注意的是娄猫,在aidl中如果引用其他aidl接口類型,需要import生闲,即使是在相同的包結構下媳溺。所以我們在IRemoteService的方法中引用LiteappCallback需要導包,在IRemoteService.aidl文件中加入import com.main.mainapplication.LiteappCallback;

至此,aidl基本定義完畢碍讯。

2.創(chuàng)建main中的service悬蔽。
這里我們創(chuàng)建叫l(wèi)iteservice的服務,其中需要實現IRemoteService冲茸。

package com.main.mainapplication.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import com.main.mainapplication.IRemoteService;
import com.main.mainapplication.LiteappCallback;
/** 
* Date: 2016-04-15 
* Time: 12:58 
* Description: FIXME 
*/
public class LiteService extends Service{    
@Nullable    
@Override    
public IBinder onBind(Intent intent) { 
       return null;    
}   
private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {        
@Override        
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {        }        
@Override        
public String getPlayInfo(String couldId, LiteappCallback callback) throws RemoteException {            
requestPlayUrl(couldId, callback);            
return "http://";        
}    
};    
private void requestPlayUrl(String couldId, LiteappCallback callback) {        //TODO 進行異步操作        
//在異步請求里如果成功執(zhí)行callback.getPlayUrlSuccess(playurl);        //如果失敗之執(zhí)行callback.getPlayUrlFail(message);    
}
}

其中具體的異步請求就不寫了屯阀,總之會回調callback的兩個方法缅帘。由于是異步的處理轴术,所以這里getPlayInfo方法的直接返回結果并沒有什么卵用。
別忘了我們需要在main應用的清單文件中注冊service:

<service android:name="com.main.mainapplication.service.LiteService">   
    <intent-filter>        
        <action android:name="com.main.mainapplication.intent.action.FORURL"/>    
    </intent-filter>
</service>

這里采用隱式的調起方式钦无。

3.回到lite應用中
首先需要將main中創(chuàng)建的aidl文件copy到lite中逗栽,這里需要注意的是aidl的包名也一并copy過來:

Paste_Image.png

同樣需要make project生成對應接口文件。
由于只是事例代碼失暂,所以我就寫在liteApplication的MainActivity中了彼宠,

private IRemoteService mRemoteService;

ServiceConnection conn = new ServiceConnection() {    
@Override    
public void onServiceConnected(ComponentName name, IBinder service) {        
mRemoteService = IRemoteService.Stub.asInterface(service);   
System.out.println("bind success" + mRemoteService.toString());    
}    
@Override    
public void onServiceDisconnected(ComponentName name) {    
}
};
private final LiteappCallback.Stub callback = new LiteappCallback.Stub() {    
@Override    
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {  
}    
@Override    
public void getPlayUrlSuccess(String playUrl) throws RemoteException {        
System.out.println("playUrl: " + playUrl);    
}    
@Override    
public void getPlayUrlFail(String message) throws RemoteException {        
System.out.println("message: " + message);    
}
};

這里是先創(chuàng)建ServiceConnection鳄虱,并且實現LiteappCallback接口,getPlayUrlSuccess功能只是打印該url凭峡。這個方法會在main應用中的異步處理中調用拙已。

這里就直接在mainactivity的oncreate方法中綁定服務了,場景不一樣摧冀,需要另外處理:

Intent intent = new Intent("com.main.mainapplication.intent.action.FORURL");
intent.setPackage("com.main.mainapplication");
System.out.println("開始bind");
bindService(intent, conn, Context.BIND_AUTO_CREATE);

這里注意:Android 5.0一出來后倍踪,其中有個特性就是Service Intent must be explitict,也就是說從Lollipop開始索昂,service服務必須采用顯式意圖方式啟動.解決辦法就是增加intent.setPackage("com.main.mainapplication");設置包名建车。才可以綁定service。然后在需要的地方直接調用getPlayInfo方法椒惨。

try {    
mRemoteService.getPlayInfo("23456789", callback);
} catch (RemoteException e) { 
e.printStackTrace();
}

此時缤至,同一個手機上都裝了main應用和lite應用后,main應用帶數據到lite之后康谆,lite通過綁定service领斥,調用getPlayInfo方法,然后會在service中異步請求獲取后調用了lite中的getPlayUrlSuccess方法后沃暗,成功在lite中拿到了main中請求的url數據戒突,然后lite中再處理播放的邏輯。

至此描睦,aidl實現基本完成膊存。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市忱叭,隨后出現的幾起案子隔崎,更是在濱河造成了極大的恐慌,老刑警劉巖韵丑,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爵卒,死亡現場離奇詭異,居然都是意外死亡撵彻,警方通過查閱死者的電腦和手機钓株,發(fā)現死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來陌僵,“玉大人轴合,你說我怎么就攤上這事⊥攵蹋” “怎么了受葛?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我总滩,道長纲堵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任闰渔,我火速辦了婚禮席函,結果婚禮上,老公的妹妹穿的比我還像新娘冈涧。我一直安慰自己向挖,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布炕舵。 她就那樣靜靜地躺著何之,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咽筋。 梳的紋絲不亂的頭發(fā)上溶推,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音奸攻,去河邊找鬼蒜危。 笑死,一個胖子當著我的面吹牛睹耐,可吹牛的內容都是我干的辐赞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼硝训,長吁一口氣:“原來是場噩夢啊……” “哼响委!你這毒婦竟也來了?” 一聲冷哼從身側響起窖梁,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤赘风,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后纵刘,有當地人在樹林里發(fā)現了一具尸體邀窃,經...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年假哎,在試婚紗的時候發(fā)現自己被綠了瞬捕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡舵抹,死狀恐怖肪虎,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情掏父,我是刑警寧澤笋轨,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站赊淑,受9級特大地震影響爵政,放射性物質發(fā)生泄漏。R本人自食惡果不足惜陶缺,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一钾挟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧饱岸,春花似錦掺出、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至百框,卻和暖如春闲礼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铐维。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工柬泽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嫁蛇。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓锨并,卻偏偏與公主長得像,于是被迫代替她去往敵國和親睬棚。 傳聞我的和親對象是個殘疾皇子第煮,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內容