概述
上篇介绍了aidl传递基本类型的方法,建议先看这篇
安卓aidl的简单实现教程
下面介绍如何发送自定义类型消息
一.首先还是先搞定服务端
1.首先在服务端创建Person.java,实现Parcelable接口
如何实现请看这篇,如何实现Parcelable接口,已经写的很好很完美了,我就不重写了。
下面是代码
public class Person implements Parcelable {
private Integer id;
private String name;
public Person() {
}
public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
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(this.id);
dest.writeString(this.name);
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
return new Person(source.readInt(), source.readString());
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
2.创建Person.aidl,内容就两行,注意包名要一致,这里也许会提示类重复,可以选择新建file,名字为Person.aidl,将代码拷贝即可。
package wj.com.aidl_service;
parcelable Person;
3.创建IPersonService.aidl,代码如下,只有一个save方法。
package wj.com.aidl_service;
import wj.com.aidl_service.Person;
interface IPersonService {
void save(in Person person);
}
4.rebuild一下
5.创建PersonService服务,创建内部类PersonBinder继承IPersonService.Stub,在PersonService的onBind方法中返回PersonBinder对象。
public class PersonService extends Service {
public PersonService() {
}
@Override
public IBinder onBind(Intent intent) {
return new PersonBinder();
}
public class PersonBinder extends IPersonService.Stub {
@Override
public void save(Person person) throws RemoteException {
Log.i("waaa", person.getName());
}
}
}
这里同注意Manifest要注册PersonService,并设置action
<service
android:name=".PersonService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="wj.com.aidl_service.PersonService"/>
</intent-filter>
</service>
下面是服务端的结构,仅供参考
二.下面进行客户端的操作
1.将服务端的aidl文件夹整个复制到客户端的main下
2.将服务端的Person复制到客户端下,Person所在包名要与服务端中Person所在包名相同
下面是客户端结构
3.在MainActivity创建PersonConn实现ServiceConnection
4.在onServiceConnected方法中调用IPersonService.Stub.asInterface(iBinder)获取IPersonService对象
5.自定义initConnection方法绑定服务(显示调用)
6.在点击事件中获取PersonConn对象,调用initConnection方法即可。
MainActivity代码如下
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private IMyAidlInterface iMyAidlInterface;
private IPersonService iPersonService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btTest = (Button) findViewById(R.id.bt_test);
Button btPerson = (Button) findViewById(R.id.bt_person);
btTest.setOnClickListener(this);
btPerson.setOnClickListener(this);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_test:
MyConn conn = new MyConn();
conn.initConnection();
break;
case R.id.bt_person:
PersonConn personConn = new PersonConn();
personConn.initConnection();
break;
}
}
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
try {
Toast.makeText(MainActivity.this, iMyAidlInterface.getName(), Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
iMyAidlInterface = null;
}
void initConnection() {
//5.0开始服务应显示调用
Intent intent = new Intent();
intent.setAction("wj.com.aidl_service.MyService");//与服务端Manifest的MyService一致
intent.setPackage("wj.com.aidl_service");//服务端包名
bindService(intent, this, BIND_AUTO_CREATE);
}
}
private class PersonConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
iPersonService = IPersonService.Stub.asInterface(iBinder);
try {
iPersonService.save(new Person(0,"waa"));
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
iMyAidlInterface = null;
}
void initConnection() {
//5.0开始服务应显示调用
Intent intent = new Intent();
intent.setAction("wj.com.aidl_service.PersonService");//与服务端Manifest的MyService一致
intent.setPackage("wj.com.aidl_service");//服务端包名
bindService(intent, this, BIND_AUTO_CREATE);
}
}
}
布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Button
android:id="@+id/bt_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="aidl" />
<Button
android:id="@+id/bt_person"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Person" />
</LinearLayout>
这样就算完成了,点击bt_person后,客户端就把new Person(0,”waa”)传递给服务端,服务端调用Log.i(“waaa”, person.getName());打印log。
同样要注意的是:
1.服务端service必须在manifest中注册,并设置action
2.服务端必须启动,客户端才能调取服务中的方法
3.由于5.0开始服务必须显示调用,setAction()要与service在manifest中注册的action相同,setPackage为服务端的包名。
否则报错java.lang.IllegalArgumentException: Service Intent must be explicit: Intent。
4.aidl文件保持一样,记得rebuild。
以上就是aidl的简单使用了,使用到的代码已经全部贴上,
我的Androidstudio版本2.2,手机系统7.0,亲测有效。
qq群492462202欢迎交流。
参考资料:
本篇整体思路流程参考自该博客,非常感谢!
https://www.cnblogs.com/0616–ataozhijia/p/4952441.html
觉得有用就赞助一下吧!
最后
以上就是复杂世界为你收集整理的安卓aidl进阶,发送自定义类型消息的全部内容,希望文章能够帮你解决安卓aidl进阶,发送自定义类型消息所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复