概述
AIDL实践一:自定义类型传递
本文是慕课网视频的练习,视频网址:http://www.imooc.com/learn/606
- 开发工具: Android Studio
一.编写服务端:
- 创建项目
- 在java目录同级下创建aidl文件夹
创建IPersonAidl.aidl文件,文件内容如下:
// IAddAidl.aidl
package com.lyj.aidldemo2;
// Declare any non-default types here with import statements
import com.lyj.aidldemo2.Person;
interface IPersonAidl {
//注意 in 表示输入,否则编译不过
List<Person> addPerson(in Person person);
}
在java文件夹下创建类Person.java,有年龄和姓名两个字段,并实现Parcelable接口,代码如下:
//实现Parcelable
public class Person implements Parcelable{
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public Person(Parcel in) {
//注意,此处顺序要和writeToParcel中的顺序一致
age = in.readInt();
name = in.readString();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
//重写toString方法
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + ''' +
'}';
}
}
在Aidl文件夹中创建Person.java同名的Person.aidl文件,文件内容如下:
package com.lyj.aidldemo2;
parcelable Person;
- 在Java目录下创建远程服务IMyService,代码如下
public class IMyService extends Service {
private List<Person> persons;
@Nullable
@Override
public IBinder onBind(Intent intent) {
//绑定服务时初始化persons对象
persons = new ArrayList<Person>();
return iBinder;
}
//实例化iBinder对象,实现IPersonAidl的方法
private IBinder iBinder = new IPersonAidl.Stub(){
@Override
public List<Person> addPerson(Person person) throws RemoteException {
persons.add(person);
return persons;
}
};
}
在这个类中,实现了IAddAidl中的方法,在客户端绑定服务的时候,返回iBinder
- 在Manifest中注册:
<service android:name=".MyService"
android:process=":remote"
android:exported="true"/>
process 表示是一个远程服务
exported属性值为true,表示其它app可以引用这个服务。
到目前为止,服务端的工作已经完成了。
二.客户端编写
- 新建一个项目或新建一个module,名字为client
- 将服务端的aidl文件夹拷贝到client下,和java目录同级,注意,拷贝后检查包名一定要和服务端的包名一样
- 在java下新建一个包,包名和服务端Person.java的包名一致,将person.java拷贝到此包下面,然后编译
- 编写客户端布局和代码
- 布局就是两个edittext输入年龄和姓名,一个button点击时触发远程服务的addPerson方法,一个TextView显示结果,此处就略去
- 代码如下:
public class MainActivity extends AppCompatActivity {
private EditText et_name,et_age;
private Button btn_print;
private TextView tv_content;
private IPersonAidl iPersonAidl;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iPersonAidl = IPersonAidl.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
iPersonAidl = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initAction();
bindService();
}
private void initAction() {
btn_print.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = et_name.getText().toString().trim();
int age = Integer.parseInt(et_age.getText().toString().trim());
Person person = new Person(age,name);
try {
List<Person> persons = iPersonAidl.addPerson(person);
tv_content.setText(persons.get(0).toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private void bindService() {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.lyj.aidldemo2","com.lyj.aidldemo2.IMyService"));
bindService(intent,conn, Context.BIND_AUTO_CREATE);
}
private void initView() {
et_age = (EditText) findViewById(R.id.et_age);
et_name = (EditText) findViewById(R.id.et_name);
btn_print = (Button) findViewById(R.id.btn_print);
tv_content = (TextView) findViewById(R.id.tv_content);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
}
首先,在onCreate()的时候绑定了服务
其次,在服务连接(onServiceConnect())时,获取IPersonAidl对象,
最后,在点击的时候,iAddAidl调用其addPerson(Person person)方法
三.运行
先运行服务端app,然后运行客户端app,在客户端的app中并未实现加到方法,却调用服务端的方法,实现了加的运算。
四.总结:
可以看到,自定义类型的传递和基本类型的传递还是很相似的,但是要注意一下几点:
1. Person.java 和 Person.aidl文件名要相同,且Person.java中必须实现序列化
2. aidi接口中要输入的参数前面要加 in ,否则编译不过,会报如下错误:
C:LYJnewAidlDemo2appsrcmainaidlcomlyjaidldemo2IPersonAidl.aidl:9 parameter 1: 'Person person' can be an out parameter, so you must declare it as in, out or inout.
Error:Execution failed for task ':app:compileDebugAidl'.
> java.lang.RuntimeException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:UsersyuAppDataLocalAndroidsdkbuild-tools22.0.1aidl.exe'' finished with non-zero exit value 1
3. 在客户端拷贝包的时候一定要把aidl文件和java文件都拷过去,拷完检查包名是否完整
最后
以上就是称心水杯为你收集整理的AIDL实践二:自定义数据类型AIDL实践一:自定义类型传递的全部内容,希望文章能够帮你解决AIDL实践二:自定义数据类型AIDL实践一:自定义类型传递所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复