b.应用之间绑定
i.使用AIDL定义接口, 刷新工程, Eclipse会自动生成一个Java接口ii.Service中定义一个类继承Stub类, 实现抽象方法
iii.Activity中收到IBinder之后调用Stub.asInterface()方法把IBinder转为接口类型
调用者和服务在不同的应用中。
定义一个借口是其在两个应用中都可以使用,使用一个叫aidl的东西 android interface definition language
原来的接口是用.java定义的。为InvokeInterface.java
package com.itheima.bindservice;
public interface InvokeInterface {
public void pay(); // 服务要提供的方法事先写在接口中
public void play();
}
将此文件重名为InvokeInterface.aidl 去掉pulic
package com.itheima.remoteservice.invokeinterface;
import com.itheima.removeservice.bean.Person;
interface InvokeInterface {
boolean pay(in Person p, int amount); // 服务要提供的方法事先写在接口中
}
刷新工程, Eclipse会自动在本工程的gen目录中生成一个Java接口。
在这个生成的文件中,有一个抽象stub类实现了我们要用的InvokeInterface的接口,所以我们代码中只用继承这个stub类就可以了.
这个.aidl文件在两个应用中都有一份。
写一个调用者的应用:
package com.itheima.remoteactivity;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import com.itheima.remoteservice.invokeinterface.InvokeInterface;
import com.itheima.remoteservice.invokeinterface.InvokeInterface.Stub;
import com.itheima.removeservice.bean.Person;
public class MainActivity extends Activity {
private InvokeInterface ii;
private ServiceConnection conn = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) { // 在服务被杀的时候执行(解绑时不会执行)
}
public void onServiceConnected(ComponentName name, IBinder iBinder) {
ii = Stub.asInterface(iBinder); // Stub.asInterface() 可以把IBinder转为接口类型
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService(new Intent("itheima.service.REMOTE_SERVICE") , conn, BIND_AUTO_CREATE); // 绑定服务, bindService(), 得到IBinder
// 上1篇是在同一个应用内,用类名就可直接调用,这不是在同个类中,所以意图的参数,是用的名称。流程还是一样,只是把代码放到两个应用中
// 调用远程服务,远程服务中返回一个mybind.。 上面的public void onServiceConnected(ComponentName name, IBinder iBinder) 一句拿到这个
// ibinder。然后ii = Stub.asInterface(iBinder);强制转换为借口类型,然后等待按钮调用pay。
}
public void pay(View v) throws Exception {
System.out.println(ii.pay(new Person(101, "FD", 29), 150)); // 通过IBinder, 调用Service中的支付
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn); // 解绑服务, unbindService()
}
}
再写一个服务 myservice,java
package com.itheima.remoteservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import com.itheima.remoteservice.invokeinterface.InvokeInterface.Stub;
import com.itheima.removeservice.bean.Person;
public class RemoteService extends Service {
@Override
public void onCreate() {
System.out.println("Remote onCreate");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) { // bindService()时会执行
System.out.println("Remote onBind");
return new MyBinder();
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("Remote onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
System.out.println("Remote onDestroy");
super.onDestroy();
}
private class MyBinder extends Stub {
public boolean pay(Person p, int amount) throws RemoteException {
System.out.println("向" + p.getName() + "支付" + amount);
return amount < 100;
}
}
}