例如:APPA绑定APPB中的服务。
绑定远程服务的步骤:
1:在APPB中,将暴露出来的IMiddlePerson.java改为IMiddlePerson.aidl文件,此时会在gen目录下生成与IMiddlePerson.aidl相同包名的IMiddlePerson.java文件,进去会发现,IMiddlePerson的子类Stub继承Binder并实现IMiddlePerson.java.
2:由上可知在服务中将MiddlePerson继承IMiddlePerson.Stub即可。
3:在APPA的src下新建一个与APPB的IMiddlePerson.aidl相同的包名,并在该包名下建一个相同的IMiddlePerson.aidl相同的文件,此
会发现在gen目录下也会生成相应的IMiddlePerson.java文件(与APPB中的一样)
4:在APPA的Activity中的子类ServiceConnection中的onServiceConnected中将service转换为IMiddlePerson,如下:
IMiddlePerson MP=mp=IMiddlePerson.Stub.asInterface(service)
需要注意的是绑定远程服务,不可以调用远程服务的跟远程服务有密切关系的方法,例如Toast,可以调用远程服务的普通方法,待解决。
APPB端:
APPB端如下图:新建一个.aidl文件,这是一个接口文件。
经过上一步的操作,会在APPB的gen目录下生成相同包名下的.java文件,进入该.java文件可知,该.java中的Stub子类继承了Binder并实现了该.java接口文件,如下图:
由上一步可知,我们只需将APPB的Service中的内部类(这里以MiddlePerson为例)继承IMiddlePerson.Stub即可,如下图:
APPA端:
完整实例代码:
public class MyService extends Service {
/**
* 与服务绑定成功的方法
* 当绑定服务成功,与服务建立关联时,返回中间人
*/
@Override
public IBinder onBind(Intent intent) {
System.out.println("服务绑定成功onBind");
return new MiddlePerson();
}
/**
* 与服务断开绑定的方法
*/
@Override
public boolean onUnbind(Intent intent) {
System.out.println("与服务断开绑定onUnbind");
return super.onUnbind(intent);
}
/**
* 服务创建成功的方法
*/
@Override
public void onCreate() {
System.out.println("服务创建成功onCreate");
super.onCreate();
}
/**
* 服务获取到开启指令的方法
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("服务获取到开启指令onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
/**
* 服务被销毁的方法
*/
@Override
public void onDestroy() {
System.out.println("服务被销毁onDestroy");
super.onDestroy();
}
/**
* 服务内部的方法
*/
public void methodInService(){
System.out.println("我是服务内部的方法,我被调用了");//可以执行
//不可以执行,应该把Context作为参数传递过来
Toast.makeText(this, "我是服务内部的方法我被调用了", Toast.LENGTH_SHORT).show();
}
/**
* 外部空间要调用服务内部的方法,需要通过中间人
* 当中间人的方法很多时,接口可以很好的保护这些方法
* MiddlePerson通过继承Stub,间接继承了Binder(Binder实现了IBinder)且实现了IMiddlePerson接口,通过这
* 样,即可通过Service的onBind将该MiddlePerson return给绑定者,绑定者也可通过return过来的MiddlePerson调用IMiddlePerson
* 中的callMethodInService()方法,在该callMethodInService()方法中就可调用Service内部的方法。
*
*/
private class MiddlePerson extends IMiddlePerson.Stub{
@Override
public void callMethodInService() {
methodInService();
}
}
}
APPB的.aidl代码:
package com.yin.yuanchengdfw;
interface IMiddlePerson {
void callMethodInService();
}
APPA端绑定服务的代码
public class MainActivity extends FragmentActivity {
private MyConn conn=null;
IMiddlePerson mp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 绑定远程的服务
*/
public void bind(View v){
Intent intent = new Intent();
intent.setAction("com.yin.yuanchengdfw.MyService.far");
if(conn == null){
conn=new MyConn();
}
bindService(intent, conn, BIND_AUTO_CREATE);
System.out.println("执行bindService");
}
/**
* 解除绑定远程的服务
*/
public void unbind(View v){
if(conn!=null){
unbindService(conn);
System.out.println("执行unbindService");
conn = null;
}
}
/**
* 调用远程服务的方法
*/
public void call(View v){
try {
mp.callMethodInService();
} catch (RemoteException e) {
System.out.println("通过中间人调服务内部的方法时出现异常");
e.printStackTrace();
}
}
/**
* 监视与远程服务连接状态的类
* @author Administrator
*
*/
public class MyConn implements ServiceConnection {
/**
* 当远程服务绑定成功,与远程服务建立连接时,调用onServiceConnected方法
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("与外部服务连接成功");
mp=IMiddlePerson.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("与外部服务断开连接");
}
}
@Override
protected void onDestroy() {
if(conn != null){
unbindService(conn);
conn = null;
System.out.println("本地activity执行onDestroy");
}
super.onDestroy();
}
}
APPA端.aidl代码
package com.yin.yuanchengdfw;
interface IMiddlePerson {
void callMethodInService();
}