AIDL(Android Interface Definition Language):安卓接口定义语言的缩写,是一种android内部进程通信接口的描述语言,通过它可以定义进程间的通信接口。
本文参考:http://www.runoob.com/w3cnote/android-tutorial-service-3.html ,把服务端实现和客户端实现合在一起在同一项目下进行实现,因此,对概念的介绍理解可查看参考网页。
环境:
android studio 2.3.3
模拟器:BlueStacks
项目主要目录:
Step 1:创建Person.aidl和Salary.aidl的文件
Person.aidl
// Person.aidl
package com.example.aidltest;
parcelable Person;
Salary.aidl:
// Salary.aidl
package com.example.aidltest;
parcelable Salary;
Step 2:分别建立Person类与Salary类,实现Parcelable接口,重写对应的方法
Person.java:
package com.example.aidltest;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by Jinato on 2017/9/30.
*/
public class Person implements Parcelable{
private Integer id;
private String name;
public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
public Person() {
}
protected Person(Parcel in) {
name = in.readString();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in.readInt(), in.readString());
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (id != null ? !id.equals(person.id) : person.id != null) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
Salary.java:
package com.example.aidltest;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by Jinato on 2017/9/30.
*/
public class Salary implements Parcelable{
private String type;
private Integer salary;
public Salary() {
}
public Salary(String type, Integer salary) {
this.type = type;
this.salary = salary;
}
protected Salary(Parcel in) {
type = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(type);
dest.writeInt(salary);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Salary> CREATOR = new Creator<Salary>() {
@Override
public Salary createFromParcel(Parcel in) {
return new Salary(in.readString(), in.readInt());
}
@Override
public Salary[] newArray(int size) {
return new Salary[size];
}
};
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getSalary() {
return salary;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
@Override
public String toString() {
return "工作:'" + type + '\'' + ", 薪水:" + salary ;
}
}
Step 3:创建一个ISalary.aidl的文件,在里面写一个简单的获取工资信息和查询Person的方法
// ISalary.aidl
package com.example.aidltest;
import com.example.aidltest.Salary;
import com.example.aidltest.Person;
// Declare any non-default types here with import statements
interface ISalary {
Salary getMsg(in Person owner);
String queryPerson(int num);
}
Step 4:编写AidlService
package com.example.aidltest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import com.example.aidltest.Person;
import com.example.aidltest.Salary;
import com.example.aidltest.ISalary.Stub;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Jinato on 2017/9/30.
*/
public class AidlService extends Service {
private static String[] names = {"AA", "BB", "CC", "DD"};
private SalaryBinder salaryBinder;
private static Map<Person,Salary> ss = new HashMap<Person, Salary>();
//初始化Map集合,这里在静态代码块中进行初始化,当然你可也以在构造方法中完成初始化
static
{
ss.put(new Person(1, names[0]), new Salary("码农", 2000));
ss.put(new Person(2, names[1]), new Salary("歌手", 20000));
ss.put(new Person(3, names[2]), new Salary("学生", 20));
ss.put(new Person(4, names[3]), new Salary("老师", 2000));
}
@Override
public void onCreate() {
super.onCreate();
salaryBinder = new SalaryBinder();
}
@Override
public void onDestroy() {
System.out.println("服务结束");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return salaryBinder;
}
public class SalaryBinder extends Stub {
@Override
public Salary getMsg(Person owner) throws RemoteException {
return ss.get(owner);
}
@Override
public String queryPerson(int num) throws RemoteException {
if (num > 0 && num < 5) {
return names[num - 1];
}
return null;
}
}
}
注册Service:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aidltest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".AidlService">
<intent-filter>
<action android:name="android.intent.action.AIDLService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
</application>
</manifest>
Step 5:编写布局文件
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.aidltest.MainActivity">
<TextView
android:id="@+id/txt_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="31dp"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_query"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1" />
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="请输入要查询的序号:"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
android:layout_marginTop="20dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="1.0" />
<EditText
android:id="@+id/edit_num"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:hint="请输入整数(1~4)"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
tools:layout_constraintRight_creator="1"
tools:layout_constraintLeft_creator="1" />
<Button
android:id="@+id/btn_query"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="查询"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_constraintRight_creator="1"
tools:layout_constraintLeft_creator="1"
app:layout_constraintHorizontal_bias="0.0"
tools:layout_constraintTop_creator="1"
android:layout_marginTop="33dp"
app:layout_constraintTop_toBottomOf="@+id/edit_num" />
</android.support.constraint.ConstraintLayout>
Step 6:MainActvitiy的实现定义一个ServciceConnection对象,重写对应方法,再接着在bindService,然后再Button的点击事件中获取Salary对象并显示出来
package com.example.aidltest;
import android.content.ComponentName;
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 android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "AIDL";
private EditText edit_num;
private Button btn_query;
private TextView text_show;
private ISalary salaryService;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
salaryService = ISalary.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
salaryService = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
//绑定远程Service
Intent service = new Intent("android.intent.action.AIDLService");
service.setPackage("com.example.aidltest");
bindService(service, conn, BIND_AUTO_CREATE);
btn_query.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
this.unbindService(conn);
}
private void bindViews() {
edit_num = (EditText) findViewById(R.id.edit_num);
btn_query = (Button) findViewById(R.id.btn_query);
text_show = (TextView) findViewById(R.id.txt_name);
}
@Override
public void onClick(View v) {
try {
int id = Integer.parseInt(edit_num.getText().toString());
String name = salaryService.queryPerson(id);
Salary salary = salaryService.getMsg(new Person(id, name));
text_show.setText(name + "的" + salary.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
// text_show.setText("");
}
}
运行效果:
完整代码下载:Android Studio实现AIDL跨进程通信DEMO