通过一个学生管理展示AIDL的使用
1.创建aidl文件
1.打开AndroidStudio,在工程目录右键New=>AIDL
(1)新建Student.aidl文件,相当于这是一个实体类,对应的在java侧要定义一个同名的类Student需要实现Parcelable接口,详见Parcelable的使用,需要删掉默认生成的interface Student改成parcelable Student,
// Student.aidl
package cc.funeay.sepprocesswebview;
// Declare any non-default types here with import statements
parcelable Student;
(2) 新建Student.java 在java目录下,注意Student.aidl和Sutdent.java包名要一样,
public class Student implements Parcelable {
protected Student(Parcel in) {
}
public static final Creator CREATOR = new Creator() {
@Override
public Student createFromParcel(Parcel in) {
return new Student(in);
}
@Override
public Student[] newArray(int size) {
return new Student[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
}
}
(3)新建StudentManager.aidl接口来管理Student
// StudentManager.aidl
package cc.funeay.sepprocesswebview;
// Declare any non-default types here with import statements
interface StudentManager {
/**
* 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);
void addStudent(Student s);//新增一个学生
List getStudents();//获取学生列表
}
2.生成java文件
(1)编译的时候报:"Failed to resolve 'Student'" 需要在StudentManager.aidl里面把Student接口完整路径import进来
import cc.funeay.sepprocesswebview.aidl.Student;
编译还是报错:“'cc.funeay.sepprocesswebview.aidl.Student' can be an out type, so you must declare it as in, out, or inout.”,需要添加一个tag表示参数的方向,需要把Student.aidl修改如下
// StudentManager.aidl
package cc.funeay.sepprocesswebview.aidl;
import cc.funeay.sepprocesswebview.aidl.Student;
// Declare any non-default types here with import statements
interface StudentManager {
/**
* 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);
void addStudent(inout Student s);
List getStudents();
}
发现报错:"错误: 找不到符号
符号: 方法 readFromParcel(Parcel)
位置: 类型为Student的变量 s",原来是需要Student实现readFromParcel方法,定义一下,调整Student代码如下
public class Student implements Parcelable {
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
protected Student(Parcel in) {
this.id = in.readInt();
this.name = in.readString();
}
public static final Creator CREATOR = new Creator() {
@Override
public Student createFromParcel(Parcel in) {
return new Student(in);
}
@Override
public Student[] newArray(int size) {
return new Student[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
//读的顺序要和写的顺序一致
parcel.writeInt(id);
parcel.writeString(name);
}
public void readFromParcel(Parcel parcel) {
this.id = parcel.readInt();
this.name = parcel.readString();
}
@NonNull
@Override
public String toString() {
return "id:" + id + " name:" + name;
}
}
3.编写服务端代码
StudentService.java
public class StudentService extends Service {
private List students = new ArrayList<>();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
/**
* 实现StudentManager接口
*/
private StudentManager.Stub binder = new StudentManager.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
@Override
public void addStudent(Student s) throws RemoteException {
students.add(s);
}
@Override
public List getStudents() throws RemoteException {
return students;
}
};
}
//AndroidManifest.xml 里面配置服务
4.编写客户端代码
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String BOOK_SERVICE_ACTION = "android.intent.action.BookService";
private Button btnStartService;
private StudentManager studentManager;//从service进程获取的实例
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
findViewById(R.id.tv_go_webview).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
goWebView();
}
});
btnStartService = findViewById(R.id.btn_start_service);
btnStartService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
tryStartService();
}
});
findViewById(R.id.btn_add_book).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (studentManager != null) {
try {
Student student = new Student(1, "Student-" + System.currentTimeMillis());
studentManager.addStudent(student);
disPlayStudents(studentManager.getStudents());
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
}
private void disPlayStudents(List students) {
StringBuffer sbf = new StringBuffer("学生列表:");
if (students != null) {
int size = students.size();
for (int i = 0; i < size; i++) {
sbf.append(" student --- ");
sbf.append(students.get(i).getName());
}
}
Log.d("disPlayStudents ", sbf.toString());
}
@Override
protected void onDestroy() {
stopService();
super.onDestroy();
}
private void tryStartService() {
String isConnected = btnStartService.getTag() != null ? btnStartService.getTag().toString() : "0";
if ("0".equals(isConnected)) {
//未连接
startService();
}
}
/**
* 启动service
*/
private void startService() {
Intent intent = new Intent();
intent.setAction(BOOK_SERVICE_ACTION);
intent.setPackage(getPackageName());//Android 5.0开始不再支持 隐式启动service 需要写成包名
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
/**
* 停止/解绑service
*/
private void stopService() {
unbindService(connection);
}
private void goWebView() {
Intent intent = new Intent();
intent.setClass(MainActivity.this, WebViewActivity.class);
startActivity(intent);
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
studentManager = StudentManager.Stub.asInterface(iBinder);
updateBtnStart();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
//异常的时候才会回调
studentManager = null;
updateBtnStart();
}
};
private void updateBtnStart() {
btnStartService.setTag(studentManager != null ? "1" : "0");
btnStartService.setText(studentManager != null ? "已连接" : "未连接");
}
}