赞
踩
本文主要采用AIDL实现,概念不讲,只说明具体搭建步骤,想了解AIDL的介绍和使用可以参考:
1、Android studio新建项目,创建2个module,一个命名serverApp,一个命名clientApp。
server端配置:
2、server端main目录下创建aidl目录,New->AIDL文件,完成后效果如下:
3、在IMyAidlInterface.aidl创建一个方法测试,如果想使用参数,和java一样,写好后编译一下,生成对应的java文件以便后面使用
- interface IMyAidlInterface {
- String ipcMsg();
- }
4、在java目录创建service实现IMyAidlInterface接口
- override fun onBind(intent: Intent): IBinder {
- return myBinder
- }
-
- private val myBinder = object: IMyAidlInterface.Stub(){
- override fun ipcMsg(): String {
- return "服务端返回消息"
- }
- }
5、在AndroidManifest里配置service,android:exported="true",必须配置成true,才能被其他app调用
- <service
- android:name=".IpcService"
- android:enabled="true"
- android:exported="true"/>
client端配置:
6、把刚才创建的aidl整个目录内容全拷贝到clientApp相同目录下,不要修改任何内容,同理,后期如果在server端修改了此文件,在client端需要同步一下,同样编译后生成对应java文件:
7、在MainActivity绑定service,注意ComponentName的第一个参数需要和serverApp的applicationId保持一致,第二个参数是service路径,编码过程中,遇到过几种bindService为false的情况,会在后面单独说明。
- private val serviceConnection = object : ServiceConnection {
- override fun onServiceConnected(p0: ComponentName?, iBinder: IBinder?) {
- ipcAidl = IMyAidlInterface.Stub.asInterface(iBinder)
- }
-
- override fun onServiceDisconnected(p0: ComponentName?) {
- ipcAidl = null
- }
- }
-
- private fun bindService() {
- val mIntent = Intent()
- mIntent.component = ComponentName("com.ninjuli.ipc", "com.ninjuli.ipc.IpcService")
- bindFlag = bindService(mIntent, serviceConnection, Context.BIND_AUTO_CREATE)
- }
8、最后进行测试,先安装serverApp,再安装clientApp,点击按钮,效果如下:
一个简单的跨app通信传递消息完成了,思考:如何传递对象?如何传递超过1M的数据?(为什么1M,去看看binder),会单独开一篇说明
1、在serverApp的java目录创建类Person,实现Parcelable,由于这里用的kotlin,简化代码如下
- @Parcelize
- data class Person(val name: String, val age: Int) : Parcelable
需要在build.gradle配置
- plugins {
- id 'kotlin-parcelize'
- }
2、在aidl目录创建相同Person的aidl文件
- import com.ninjuli.ipc.Person;
-
- parcelable Person;
注意这里一定要导入Person的路径,不然会报错
3、在IMyAidlInterface.aidl添加
List<Person> addPerson(in Person person);
完成后编译,把刚才java目录创建的Person类和aidl目录文件同样的拷贝一份到clientApp,名字无需修改。
4、修改IpcService,实现添加的addPerson方法
- private val myBinder = object: IMyAidlInterface.Stub(){
- override fun ipcMsg(): String {
- return "服务端返回消息"
- }
-
- override fun addPerson(person: Person): MutableList<Person> {
- return mutableListOf(person)
- }
- }
5、client添加按钮事件
- findViewById<Button>(R.id.btn1).setOnClickListener {
- val addPerson = ipcAidl?.addPerson(Person("小青", 21))
- findViewById<TextView>(R.id.text).text = addPerson?.toString()
- }
最终效果
突破binder只能传递小于1M数据,参考下面文章
特别说明编码过程中遇到的问题:
1、bindService总是返回false,百度搜索,会发现很多重复的,我出现的问题都对不上号,最后发现在安卓10以下正常,10以上就出现绑定失败,就得引申出来一个包的可见性,在manifest加上以下配置解决
<queries> <package android:name="com.ninjuli.ipc" /> </queries>
2、刚开始先安装client,再安装server,就会出现闪退问题,后来发现是在manifest配置service的时候多加了android:permission造成,去掉即可
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。