2011102013381534  

何為android中的RPC模式?

 

相信有的讀者還不是很理解,這裏和大家做一個簡單的介紹.RPC模式:Remote Procedure Call即遠程進程調用.

 

在android操作系統中,各個組件運行在各自的進程中,它們相互之間是不能訪問的.但是在程式之間不可避免的要傳遞一些對象、參數等,這就需要實現進程間的相互通信.android採用了一種輕量級的實現方式--->RPC模式來完成進程之間的通信.通過定義介面語言(android interface definition language——AIDL)來完成進程之間相互訪問的代碼.例如:#1你需要在Activity中訪問Service中的某一個方法,就可以採用這種方式來實現了.

 

AIDL語言是android的一種介面描述語言,編譯器可以通過AIDL檔生成一段代碼(注意:這段代碼是自動生成的),通過預先定義的介面達到兩個進程內部通信進程的目的.

 

詳細的說下#1例子是什麼個意思:如果需要在一個Activity中訪問另一個Service中的某個對象,需要先將對象轉化成AIDL可識別的參數(可能是多個參數),然後使用AIDL來傳遞這些參數,在消息的接收端,使用這些參數封裝成自己需要的對象.

 

總的來說:android中的AIDL RPC是通過介面來實現的,類似Windows中的COM或者Corba,但它是輕量級的,客戶端和被調用實現之間是通過代理模式實現的,代理類和被代理類實現同一個Ibinder介面.

 

接下來我就一個具體的案例和大家講講RPC模式的具體實現步驟:

 

第一步:毫無疑問,是創建AIDL介面檔.第一個問題來了,怎樣創建AIDL檔?

 

其實有這個疑問很正常,我上網搜了一些資料,問題解決.

 

在當前的Activity所在的Package右擊,new一個file,取名BookInfo.aidl.該檔中的具體內容如下:
package com.ceo.remoteservice.activity;
//BookInfo的介面檔
interface BookInfo {
void setName(String name);
void setPrice(float price);
void setPublish(String publish);

 

//顯示book資訊
String display();
}



 

該介面檔中主要包括:當前的package name,介面中的方法的聲明.編寫完成後ctrl+s,可以發現在gen檔夾下自動生成了BookInfo.java檔.如下圖所示:

 

需要注意的是該檔是系統自動生成的,盡量不要改動裏面的代碼,以免帶來不必要的錯誤.

 

第二步:聲明一個類public class BookInfoImpl extends BookInfo.Stub


 

private float price;
private String name,publish;

 

@Override
public String display() throws RemoteException {
return "書名:" + name + "價格:" + price + "出版社:" + publish;
}

 

@Override
public void setName(String name) throws RemoteException {
this.name = name;
}

 

@Override
public void setPrice(float price) throws RemoteException {
this.price = price;
}

 

@Override
public void setPublish(String publish) throws RemoteException {
this.publish = publish;
}




 

該檔下實現的這些方法都是在介面檔中定義的.

 

第三步:向客戶端暴露我們的介面,定義一個遠程服務的類public class RemoteService extends Service

 

private Stub bookifo = new BookInfoImpl();

 

在onBind方法裏面直接return bookifo;

 

第四步:主要就是MainActivity的編寫了
public class MainActivity extends Activity {
//聲明介面
private BookInfo bookinfo;
//聲明Button
private Button btnShow;
//最重要的一點就是----->實例化ServiceConnection
private ServiceConnection conn = new ServiceConnection(){

 

@Override
public synchronized void onServiceConnected(ComponentName name, IBinder service) {
//--->獲得BookInfo的介面
bookinfo = BookInfo.Stub.asInterface(service);
if(bookinfo != null) {
try {
bookinfo.setName("android開發之遠程服務的調用--jack.li");
bookinfo.setPrice(99.99f);
bookinfo.setPublish("蘇州xxx軟件有限公司");
String msg = bookinfo.display();

 

//Toast顯示
Toast.makeText(MainActivity.this, msg, 1).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}

 

@Override
public void onServiceDisconnected(ComponentName name) {

 

}

 

};

 

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

 

btnShow = (Button)findViewById(R.id.btnShow);
btnShow.setOnClickListener(new View.OnClickListener() {

 

@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.ceo.remoteservice.activity.action.MY_REMOTE_SERVICE");
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
});
}
}
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()