转载请指明出处:http://blog.youkuaiyun.com/fxdaniel/article/details/44256779
在Android中,进程间通信(IPC)采用AIDL Service技术,下面通过一个例子来看看这个技术怎么用。
首先,在Eclipse中新建两个项目 AidlServer 和 AidlClient。AidlServer 是服务提供者,它里面包含一个供其他进程访问的Service;AidlClient用来测试对远程Service的调用。
一、服务端
先看AidlServer项目。
在AidlServer项目的src目录下,新建包 com.example.aidlservice 。
接下来我们分两步走。
1. 创建aidl文件
在com.example.aidlservice 包下新建 ITime.aidl 文件。内容如下:
package com.example.aidlservice;
interface ITime
{
long getCurrentTime();
String getCurrentDate();
}
该文件中定义了一个接口ITime。
ADT工具会根据 aidl文件自动生成对应的ITime.java文件。ITime.java文件中包含一个Stub内部类,该类是Binder的子类,并且实现了ITime接口。ITime.java部分代码如下:
* This file is auto-generated. DO NOT MODIFY.
* Original file: E:\\workspace\\AidlServer\\src\\com\\example\\aidlservice\\ITime.aidl
*/
package com.example.aidlservice;
public interface ITime extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.aidlservice.ITime
{
……
- 创建 AIDL Service
在com.example.aidlservice 包下新建 AidlService.java 文件。内容如下:
package com.example.aidlservice;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.example.aidlservice.ITime.Stub;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class AidlService extends Service {
TimeBinder binder;
@Override
public IBinder onBind(Intent intent) {
// 客户端绑定到本Service的时候会调用此方法
// 通过此方法将Binder的实例返回给客户端
return binder;
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("Service created ...");
// 此处创建一个TimeBinder 的实例
binder=new TimeBinder();
}
// 此处定义一个com.example.aidlservice.ITime.Stub类的子类
// 该类的实例会返回给客户端,供客户端调用
public class TimeBinder extends Stub
{
@Override
public String getCurrentDate() throws RemoteException {
// 回调方法,返回当前日期
SimpleDateFormat format=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String date=format.format(new Date());
return date;
}
@Override
public long getCurrentTime() throws RemoteException {
// 回调方法,返回当前毫秒
return System.currentTimeMillis();
}
}
}
不要忘了在AndroidManifest.xml文件中配置Service。
<service android:name="com.example.aidlservice.AidlService"
android:enabled="true"
android:exported="true" >
<intent-filter >
<action android:name="com.example.aidlservice.action.AIDL_SERVICE"/>
</intent-filter>
</service>
至此服务端就完成了。
二、客户端
再看 AidlClient 项目。
在src目录下新建 com.example.aidlservice 包,并且将AidlServer项目中com.example.aidlservice包下的ITime.aidl拷贝到这个同名的包下面。
然后在AidlClient 项目下新建com.example.aidlclient包,在该包下新建一个Activity,起名为AidlClient,内容如下:
package com.example.aidlclient;
import com.example.aidlservice.ITime;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class AidlClient extends Activity {
Button btnGet;
TextView tvShow;
ServiceConnection conn;
// 定义一个 ITime 接口对象
ITime binder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aidl_client);
btnGet=(Button)findViewById(R.id.btn_get);
tvShow=(TextView)findViewById(R.id.tv_show);
conn=new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
binder=null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 绑定远程service成功后,回调此方法
// 第二个参数IBinder 就是远程service的代理
// 通过ITime.Stub类的asInterface方法可以将该代理转换为ITime接口的对象
binder=ITime.Stub.asInterface(service);
}
};
// 通过Intent 绑定远程Service
Intent intent=new Intent();
// 此处的Action要和AidlServer 的AndroidManifest文件中定义的一样
intent.setAction("com.example.aidlservice.action.AIDL_SERVICE");
bindService(intent, conn, Service.BIND_AUTO_CREATE);
btnGet.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(binder==null)
{
System.out.println("binder is null");
tvShow.setText("获取远程service状态失败!");
return;
}
StringBuilder sb=new StringBuilder();
try {
sb.append("当前毫秒:"+binder.getCurrentTime()+"\n");
sb.append("当前日期:"+binder.getCurrentDate());
tvShow.setText(sb.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// 解除绑定
unbindService(conn);
}
}
同样别忘了在AndroidManifest文件中配置Activity:
<activity
android:name="com.example.aidlclient.AidlClient"
android:label="@string/title_activity_aidl_client" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
至此,客户端也完成了。
三、测试
先运行AidlServer,因为没有Activity,所以我们看不到运行界面。别急,当我们运行AidlClient的时候,客户端绑定到Service,Service如果不存在的话就会被创建。
点击客户端界面上额按钮,就能通过远程Service获取当前时间,这就是Android 进程间通信。