当前位置:   article > 正文

android多个app跨进程通信(IPC)实现(一)_安卓java应用间交互

安卓java应用间交互

本文主要采用AIDL实现,概念不讲,只说明具体搭建步骤,想了解AIDL的介绍和使用可以参考:

官方AIDL简介及使用指南

1、Android studio新建项目,创建2个module,一个命名serverApp,一个命名clientApp。

server端配置:

2、server端main目录下创建aidl目录,New->AIDL文件,完成后效果如下:

3、在IMyAidlInterface.aidl创建一个方法测试,如果想使用参数,和java一样,写好后编译一下,生成对应的java文件以便后面使用

  1. interface IMyAidlInterface {
  2. String ipcMsg();
  3. }

 4、在java目录创建service实现IMyAidlInterface接口

  1. override fun onBind(intent: Intent): IBinder {
  2. return myBinder
  3. }
  4. private val myBinder = object: IMyAidlInterface.Stub(){
  5. override fun ipcMsg(): String {
  6. return "服务端返回消息"
  7. }
  8. }

5、在AndroidManifest里配置service,android:exported="true",必须配置成true,才能被其他app调用

  1. <service
  2. android:name=".IpcService"
  3. android:enabled="true"
  4. android:exported="true"/>

client端配置: 

6、把刚才创建的aidl整个目录内容全拷贝到clientApp相同目录下,不要修改任何内容,同理,后期如果在server端修改了此文件,在client端需要同步一下,同样编译后生成对应java文件:

7、在MainActivity绑定service,注意ComponentName的第一个参数需要和serverApp的applicationId保持一致,第二个参数是service路径,编码过程中,遇到过几种bindService为false的情况,会在后面单独说明

  1. private val serviceConnection = object : ServiceConnection {
  2. override fun onServiceConnected(p0: ComponentName?, iBinder: IBinder?) {
  3. ipcAidl = IMyAidlInterface.Stub.asInterface(iBinder)
  4. }
  5. override fun onServiceDisconnected(p0: ComponentName?) {
  6. ipcAidl = null
  7. }
  8. }
  9. private fun bindService() {
  10. val mIntent = Intent()
  11. mIntent.component = ComponentName("com.ninjuli.ipc", "com.ninjuli.ipc.IpcService")
  12. bindFlag = bindService(mIntent, serviceConnection, Context.BIND_AUTO_CREATE)
  13. }

 8、最后进行测试,先安装serverApp,再安装clientApp,点击按钮,效果如下:

一个简单的跨app通信传递消息完成了,思考:如何传递对象?如何传递超过1M的数据?(为什么1M,去看看binder),会单独开一篇说明

传递对象

1、在serverApp的java目录创建类Person,实现Parcelable,由于这里用的kotlin,简化代码如下

  1. @Parcelize
  2. data class Person(val name: String, val age: Int) : Parcelable

需要在build.gradle配置

  1. plugins {
  2. id 'kotlin-parcelize'
  3. }

2、在aidl目录创建相同Person的aidl文件

  1. import com.ninjuli.ipc.Person;
  2. parcelable Person;

 注意这里一定要导入Person的路径,不然会报错

3、在IMyAidlInterface.aidl添加

List<Person> addPerson(in Person person);

 完成后编译,把刚才java目录创建的Person类和aidl目录文件同样的拷贝一份到clientApp,名字无需修改。

4、修改IpcService,实现添加的addPerson方法

  1. private val myBinder = object: IMyAidlInterface.Stub(){
  2. override fun ipcMsg(): String {
  3. return "服务端返回消息"
  4. }
  5. override fun addPerson(person: Person): MutableList<Person> {
  6. return mutableListOf(person)
  7. }
  8. }

5、client添加按钮事件

  1. findViewById<Button>(R.id.btn1).setOnClickListener {
  2. val addPerson = ipcAidl?.addPerson(Person("小青", 21))
  3. findViewById<TextView>(R.id.text).text = addPerson?.toString()
  4. }

 最终效果

突破binder只能传递小于1M数据,参考下面文章

android多个app跨进程通信(IPC)实现(二)

特别说明编码过程中遇到的问题:

1、bindService总是返回false,百度搜索,会发现很多重复的,我出现的问题都对不上号,最后发现在安卓10以下正常,10以上就出现绑定失败,就得引申出来一个包的可见性,在manifest加上以下配置解决

<queries>
    <package android:name="com.ninjuli.ipc" />
</queries>

2、刚开始先安装client,再安装server,就会出现闪退问题,后来发现是在manifest配置service的时候多加了android:permission造成,去掉即可

项目地址:https://github.com/ninjuli/MultipleIPC

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/122624
推荐阅读
相关标签
  

闽ICP备14008679号