安卓aidl进阶,发送自定义类型消息

上篇介绍了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
觉得有用就赞助一下吧!
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值