进程间传递数据——AIDL传递对象

时间:2024-03-19 08:37:15

Aidl同样可以传递自定义的实现Parcelable接口的对象

服务端

1.在java中新建包com.test.aidl

2.在aidl的包下新建Student.aidl文件,建好后我们会看到在main下自动生成一个aidl文件夹,其中包含我们新建的文件,而java下的包是空的,此时我们可以把java下的包删除

文件中只有

parcelable Student;

3.在aidl文件中新建Student.java文件,Student.aidl和Student.java就是传递的对象

4.在aidl中新建MyAIDLTest.aidl,其中写本服务端可提供的方法。方法中的参数可以为Student,若参数是Student则其前必须添加in、out、inout中的一个修饰,并必须import引入该包

5.添加提供的服务MyServer.java

6.清单文件注册

结构

进程间传递数据——AIDL传递对象

MyAIDLTest.aidl

package com.test.aidl;

import com.test.aidl.Student;

interface MyAIDLTest {

    int add(int arg1, int arg2);

    String inStudentInfo(in Student student);//代表student值由客户端输入

    String outStudentInfo(out Student student);//代表student值由服务端设置

    String inOutStudentInfo(inout Student student);//代表客户端和服务端都可以设置
}
package com.test.aidl;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Administrator on 2018/6/20.
 */

public class Student implements Parcelable {
    private int id;
    private String name;
    private String className;
    private int age;

    public Student() {
    }

    public Student(int id, String name, String className, int age) {
        this.id = id;
        this.name = name;
        this.className = className;
        this.age = age;
    }

    protected Student(Parcel in) {
        id = in.readInt();
        name = in.readString();
        className = in.readString();
        age = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(name);
        dest.writeString(className);
        dest.writeInt(age);
    }

    public void readFromParcel(Parcel source) {
        id = source.readInt();
        name = source.readString();
        className = source.readString();
        age = source.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    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 int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Student.aidl

package com.test.aidl;

parcelable Student;

定义服务MyServer.java

package com.test.myservice;

import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import com.test.aidl.MyAIDLTest;
import com.test.aidl.Student;

/**
 * Created by Administrator on 2018/6/20.
 */

public class MyServer extends Service {


    MyAIDLTest.Stub stub = new MyAIDLTest.Stub() {
        @Override
        public int add(int arg1, int arg2) throws RemoteException {
            return arg1 + arg2;
        }

        @Override
        public String inStudentInfo(Student student) throws RemoteException {
            String msg = "table1" + "\n" + "----------------------------------------------" + "\n" + "|" +
                    " id " + "|" + " " +
                    "age " +
                    "|" + " name " + "|" + " className " + "|" + "\n" +
                    "----------------------------------------------" + "\n" + "|  " + student.getId() + " " +
                    "|  " + student
                    .getAge() + "  |  " + student.getName() + "   |     " + student.getClassName() + "   | " +
                    "\n" + "----------------------------------------------";
            return msg;
        }

        @Override
        public String outStudentInfo(Student student) throws RemoteException {
            String msg = student.getId() + " " +
                    "|  " + student
                    .getAge() + "  |  " + student.getName() + "   |     " + student.getClassName() + "   | ";
            return msg;
        }

        @Override
        public String inOutStudentInfo(Student student) throws RemoteException {
            student.setClassName("090411");
            student.setAge(22);
            String msg = "table3" + "\n" + "----------------------------------------------" + "\n" + "|" +
                    " id " + "|" + " " +
                    "age " +
                    "|" + " name " + "|" + " className " + "|" + "\n" +
                    "----------------------------------------------" + "\n" + "|  " + student.getId() + " " +
                    "|  " + student
                    .getAge() + "  |  " + student.getName() + "   |     " + student.getClassName() + "   | " +
                    "\n" + "----------------------------------------------";
            return msg;
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        Log.v("PDA", "MyServer_onCreate");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return stub;
    }

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
        Log.v("PDA", "MyServer_onRebind");
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.v("PDA", "MyServer_onUnbind");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v("PDA", "MyServer_onDestroy");
    }

    /**
     * get current process name
     *
     * @param context
     * @return
     */
    private String getCurProcessName(Context context) {
        int pid = android.os.Process.myPid();
        ActivityManager mActivityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager
                .getRunningAppProcesses()) {
            if (appProcess.pid == pid) {
                return appProcess.processName;
            }
        }
        return null;
    }
}

客户端

1.把服务端的aidl文件夹复制到客户端

2.在主页中启动服务,并拿到MyAIDLTest对象

结构

进程间传递数据——AIDL传递对象

进程间传递数据——AIDL传递对象

package androidpos.zy.com.aidltesttwoclient;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.test.aidl.MyAIDLTest;
import com.test.aidl.Student;

public class MainActivity extends AppCompatActivity {

    private EditText et_id;
    private EditText et_name;
    private EditText et_className;
    private EditText et_age;
    private EditText et_result;
    private Button btn_tj;
    private MyAIDLTest myAIDLTest;

    private ServiceConnection connection = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                myAIDLTest = MyAIDLTest.Stub.asInterface(iBinder);
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {

            }
        };
        et_id = (EditText) findViewById(R.id.et_id);
        et_name = (EditText) findViewById(R.id.et_name);
        et_className = (EditText) findViewById(R.id.et_className);
        et_age = (EditText) findViewById(R.id.et_age);
        et_result = (EditText) findViewById(R.id.et_result);
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("androidpos.zy.com.aidltesttwo", "com.test.myservice.MyServer"));
        intent.setAction("com.test.aidl.myaidltest");
        bindService(intent, connection, Context.BIND_AUTO_CREATE);

        findViewById(R.id.btn_tj).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    String data = myAIDLTest.add(9, 9) + "  \n" + myAIDLTest.inStudentInfo(new Student(Integer.parseInt(et_id.getText() + ""),
                            et_name.getText() + "",
                            et_className.getText() + "",
                            Integer.parseInt(et_age.getText() + "")));
                    et_result.setText(data);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }
}

当程序编译时报错找不到Student时可以在build.gradle中添加

sourceSets {
    main {
        java.srcDirs = ['src/main/java', 'src/main/aidl']
    }
}

in、out、inout三个参数的意义

String inStudentInfo(in Student student);//代表student值由客户端输入

String outStudentInfo(out Student student);//代表student值由服务端设置

String inOutStudentInfo(inout Student student);//代表客户端和服务端都可以设置