赞
踩
A应用创建aidl接口,并且创建一个Service来实现这个接口(在onBind方法里面return我们这个接口的实例)。
把A应用创建的aidl文件原封不动的搬至B应用中(注意包名类名都要一样),B应用bindService的方式来绑定A应用创建的这个Service,从而调用A应用提供的接口。
Android Studio在项目main目录右键新建,找到AIDL,它会帮我们创建文件夹和文件,默认名字IMyAidlInterface,开发者根据需求修改名字
里面有:
- interface IMyAidlInterface {
- /**
- * Demonstrates some basic types that you can use as parameters
- * and return values in AIDL.
- */
- void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
- double aDouble, String aString);
-
- //上面这个是新建的时候自己生成的,可以去掉,我们自己新建以下方法,一个get(从服务端取值),一个set(传值给服务端)
- String getHelloString();
- void setHelloString(String string);
- }
写了之后make project一下,会自动生成IMyAidlInterface类。
- public class AidlTestService extends Service {
-
- private String hello;
-
- @Override
- public void onCreate() {
- super.onCreate();
- hello = "hello";
- }
-
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return new MyBinder();
- }
-
- public class MyBinder extends IMyAidlInterface.Stub{
-
- @Override
- public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
- Log.i("xaeHu", "basicTypes: \nanInt = "+anInt
- +"\naLong = "+aLong
- +"\naBoolean = "+aBoolean
- +"\naFloat = "+aFloat
- +"\naDouble = "+aDouble
- +"\naString = "+aString
- );
- }
-
- @Override
- public String getHelloString() throws RemoteException {
- return hello;
- }
-
- @Override
- public void setHelloString(String string) throws RemoteException {
- hello = string;
- }
- }
- }
- <service android:name=".AidlTestService"
- android:enabled="true"
- android:exported="true" />
A应用的工作完成,接下来是B应用如何使用这个接口:
- <!-- 配置服务端的包名-->
- <queries>
- <package android:name="com.example.myapplication" />
- </queries>
我这边A应用包名是“com.example.myapplication”,B应用包名是“com.example.myapplication2”
注意aidl的包名要与A应用一致,否者调用方法的时候会报异常:java.lang.SecurityException: Binder invocation to an incorrect interface
放进来之后make project一下,会自动生成IMyAidlInterface类。
比如直接在MainActivity的onCreate里面去绑定服务:
- public class MainActivity extends AppCompatActivity{
- private IMyAidlInterface myAidlInterface;
- private final ServiceConnection connection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- myAidlInterface = null;
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- //点击按钮一去绑定服务
- findViewById(R.id.btn1).setOnClickListener(v -> {
- Intent intent = new Intent();
- intent.setComponent(new ComponentName("com.example.myapplication","com.example.myapplication.AidlTestService"));
- boolean re = bindService(intent, connection, Context.BIND_AUTO_CREATE);
- Log.i("xaeHu", "bindService: "+re);
- });
-
- //点击按钮2调用set方法
- findViewById(R.id.btn2).setOnClickListener(v -> {
- if(myAidlInterface != null){
- try {
- myAidlInterface.setHelloString("hello world");
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }else {
- Log.e("xaeHu", "btn2 onclick: myAidlInterface == null");
- }
- });
-
- //点击按钮3调用get方法
- findViewById(R.id.btn3).setOnClickListener(v -> {
- if(myAidlInterface != null){
- try {
- Toast.makeText(this, myAidlInterface.getHelloString(), Toast.LENGTH_SHORT).show();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }else {
- Log.e("xaeHu", "btn3 onclick: myAidlInterface == null");
- }
- });
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- unbindService(connection);
- }
- }
上面的演示是传递基本数据类型为参数的,接下来通过AIDL传递对象
先在aidl文件夹中创建实体对象文件,再在java文件夹中创建实体类,不然的话在java中创建了实体类,再在aidl中创建相同的名字会提示错误。
比如我们创建Student对象,在aidl文件夹中就是Student.aidl,里面代码很简单:
- package com.example.myapplication;
-
- parcelable Student;
然后再在java中创建Student.java,注意需要实现Parcelable:
- public class Student implements Parcelable {
- private int id;
- private String name;
- private int age;
- private int sex;
-
- public Student() {
- }
-
- public Student(int id, String name, int age, int sex) {
- this.id = id;
- this.name = name;
- this.age = age;
- this.sex = sex;
- }
-
- protected Student(Parcel in) {
- id = in.readInt();
- name = in.readString();
- age = in.readInt();
- sex = in.readInt();
- }
-
- public static final Creator<Student> CREATOR = new Creator<Student>() {
- @Override
- public Student createFromParcel(Parcel in) {
- return new Student(in);
- }
-
- @Override
- public Student[] newArray(int size) {
- return new Student[size];
- }
- };
-
- public String getName() {
- return name;
- }
-
- public int getAge() {
- return age;
- }
-
- public int getSex() {
- return sex;
- }
-
- public int getId() {
- return id;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(id);
- dest.writeString(name);
- dest.writeInt(age);
- dest.writeInt(sex);
- }
-
- @Override
- public String toString() {
- return "Student{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", age=" + age +
- ", sex=" + sex +
- '}';
- }
- }
在aidl接口中添加方法:(注意addStudent(in Student student);参数需要添加in表示接收参数,另外有out、inout)
- // IMyAidlInterface.aidl
- package com.example.myapplication;
-
- import com.example.myapplication.Student;
- // Declare any non-default types here with import statements
-
- interface IMyAidlInterface {
- /**
- * Demonstrates some basic types that you can use as parameters
- * and return values in AIDL.
- */
- void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
- double aDouble, String aString);
-
- String getHelloString();
- void setHelloString(String string);
-
- void addStudent(in Student student);
- Student getStudent(int id);
- }
服务中实现这两个方法:
- private Map<Integer,Student> studentMap;
-
- @Override
- public void addStudent(Student student) throws RemoteException {
- Log.i("xaeHu", "addStudent: "+student);
- if(studentMap == null){
- studentMap = new HashMap<>();
- }
- studentMap.put(student.getId(), student);
- }
-
- @Override
- public Student getStudent(int id) throws RemoteException {
- if(studentMap != null){
- Student student = studentMap.get(id);
- Log.i("xaeHu", id + " -> getStudent: "+student);
- return student;
- }
- Log.i("xaeHu", id + " -> getStudent: null");
- return null;
- }
同样的把aidl文件和类搬过来,注意实体对象的包名需要与A应用包名一致:
然后同样的,在绑定服务之后就可以调用了:
- myAidlInterface.addStudent(new Student(1,"student1",26,0));
- myAidlInterface.addStudent(new Student(2,"student2",27,1));
-
- Log.i("xaeHu", "getStudent1: "+myAidlInterface.getStudent(1));
- Log.i("xaeHu", "getStudent2: "+myAidlInterface.getStudent(2));
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。