在過去的技術中,Corba可以實現跨進程的調用;在Java技術中,RMI也可以實現跨進程的調用;在Android中類似可以使用AIDL服務跨進程調用Service。
Android的遠程Service調用與Java的RMI基本相似,一樣都是先定義一個遠程調用接口,然後為該接口提供一個實現類即可。與RMI不同的是,客戶端訪問Service時,Android並不是直接返回Service對象給客戶端。
在Android中綁定本地Service時,返回的是一個IBinder對象;而訪問遠程Service時,是將IBinder的代理返回給客戶端,當客戶端獲得IBinder對象的代理後,就可以通過IBinder對象去回調遠程Service的屬性和方法瞭。
示例如下:
創建AIDL文件:
AIDL:指Android Interface Definition Language
註意:AIDL定義接口的源代碼必須以.aidl結尾;
AIDL接口中用到的數據類型,除瞭基本類型、String、List 、Map、CharSequence之外,其他類型都需要導包,即使在同一包中也需導包。
在Service端和客戶端都需要為該接口提供實現。使用ADT工具進行開發,會自動為AIDL接口生成實現。
這是AIDL源代碼的一個簡單例子:
[java]
package com.lovo.service;
interface IMessage{
int getFlag();
String getMessage(String msg);
}
package com.lovo.service;
interface IMessage{
int getFlag();
String getMessage(String msg);
}自動生成的AIDL實現,在此不給出。
遠程的Service:
[java]
package com.lovo.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class RemoteService extends Service {
@Override
public IBinder onBind(Intent intent) {
MyMessage message = new MyMessage();
return message;
}
}
package com.lovo.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class RemoteService extends Service {
@Override
public IBinder onBind(Intent intent) {
MyMessage message = new MyMessage();
return message;
}
}
MyMessage類(IMessage的實現類):
[java]
package com.lovo.service;
public class MyMessage extends IMessage.Stub {
@Override
public int getFlag() {
return 100;
}
@Override
public String getMessage(String msg) {
return msg + "Android!";
}
}
package com.lovo.service;
public class MyMessage extends IMessage.Stub {
@Override
public int getFlag() {
return 100;
}
@Override
public String getMessage(String msg) {
return msg + "Android!";
}
}
客戶端的Activity:
[java]
package com.lovo.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.lovo.conn.RemoteServiceConnection;
import com.lovo.lesson10.R;
public class StartRemoteActivity extends Activity {
private Button startServiceBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_main);
startServiceBtn = (Button) findViewById(R.id.remote_main_btn_startserver);
startServiceBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.lovo.service.REMOTE_SERVICE");
bindService(intent, new RemoteServiceConnection(),
BIND_AUTO_CREATE);
}
});
}
}
package com.lovo.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.lovo.conn.RemoteServiceConnection;
import com.lovo.lesson10.R;
public class StartRemoteActivity extends Activity {
private Button startServiceBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_main);
startServiceBtn = (Button) findViewById(R.id.remote_main_btn_startserver);
startServiceBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.lovo.service.REMOTE_SERVICE");
bindService(intent, new RemoteServiceConnection(),
BIND_AUTO_CREATE);
}
});
}
}
客戶端的ServiceConnection的實現類(RemoteServiceConnection):
[java]
package com.lovo.conn;
import com.lovo.service.IMessage;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class RemoteServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 將遠程的代理對象轉換成真實對象
IMessage message = IMessage.Stub.asInterface(service);
try {
Log.i("訪問遠程方法:",
message.getFlag() + " " + message.getMessage("I like "));
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
package com.lovo.conn;
import com.lovo.service.IMessage;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class RemoteServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 將遠程的代理對象轉換成真實對象
IMessage message = IMessage.Stub.asInterface(service);
try {
Log.i("訪問遠程方法:",
message.getFlag() + " " + message.getMessage("I like "));
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
佈局文件隻有一個按鈕在此省略不寫。本文隻是簡單地調用瞭遠程的方法,在實際中可以使用AIDL傳遞復雜數據。