最常见的的是我们通过特定的 Action 或者 data 启动另外一个应用的 Activity 或者 service。我们可以将要传递的数据封装在 bundle 当中。
- 文件共享
两个应用读取某个文件,从而达到进程通讯的问题,不过这种方法需要处理好文件锁的问题,不然很容易引发数据错乱。
- 使用 Messenger
Messenger 进行进程间的通讯是串行的,而且是单向的,如果客户端和服务端想进行双向通讯,需要维护两个 Messenger,相对比较麻烦
- 使用 AIDL
aidl 一般用来进程通讯。一般来说,主要有两种角色,客户端 (Client)和服务端(Server)。
服务端
一般用来处理客户端的请求,他把与客户端通讯的方式抽象成接口,并编写成 AIDL 文件。
通常服务端需要实现一个 Service,来处理客户端的请求
客户端
通常我们需要将服务端 的 AIDL 文件 copy 过来,并通过 Intent 的方式来启动我们服务端的 Service。
接下来让我们一起来实现一个简单功能,通过一哥 app(Clilent) 唤起另外一个 APP (Server),并进行两者之间的通讯。首先,我们先来看一下服务端的实现。
服务端的实现,一般来说,需要以下步骤:
-
将请求抽象成接口,并编写 aidl 文件;
-
编写一个 Service,实现接口,处理客户端的请求,并将 binder 返回回去;
-
在 AndroidManifet 配置 Service,将我们的 Service 暴露出去。
将请求抽象成接口,编写 aidl 文件
一般来说, AIDL 文件支持以下类型
-
Java 编程语言中的所有原语类型(如 int、long、char、boolean 等等)
-
String
-
CharSequence
-
List
List 中的所有元素都必须是以上列表中支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类型。 可选择将 List 用作“通用”类(例如,List)。另一端实际接收的具体类始终是 ArrayList,但生成的方法使用的是 List 接口。
- Map
Map 中的所有元素都必须是以上列表中支持的数据类型、其他 AIDL 生成的接口或您声明的可打包类型。 不支持通用 Map(如 Map<String,Integer> 形式的 Map)。 另一端实际接收的具体类始终是 HashMap,但生成的方法使用的是 Map 接口。
- 实现 Parceable 的自定义类型
注意事项
-
在 aidl 文件中,除了 Java 编程语言中的所有原语类型、String、CharSequence、List、Map,其他在 AIDL 文件中用到的类,你必须使用 import 语句导入,否则会报错。
-
当你使用实现Parceable 的自定义类型的时候,当其作为参数的时候,你必须为其制定是输入或者是输出参数。
in 表示输入参数,即服务端可以修改该类型
out 表示输出参数,即客户端可以修改该类型,客户端不行
inout 表示客户端和服务端都可以修改该类型
如
void onSuccess(int code,in MusicInfo musicInfo);
有人可能会这样想,既然 inout 表示客户端和服务端都可以修改该类型,那我们平时在写 aidl 文件的时候,直接在方法参数前面加上 inout 修饰就 OK了,省得去区分。
这样做法当然不行,既然双方都可以修改,那系统的开销肯定会比较大。就好比管道一样。
说了这么多,接下来让我们一起来看一下例子 IEasyService.aidl
package xj.musicserver.easy;
// Declare any non-default types here with import statements
interface IEasyService {
/**
-
Demonstrates some basic types that you can use as parameters
-
and return values in AIDL.
*/
void connect(String mes);
void disConnect(String mes);
}
这个 aidl 文件很接口,只有两个方法,connect 和 disConnect 方法。
这里我们把 aidl 文跟 Java 文件中放在一起,需要在 build.gradle 中配置
sourceSets {
main {
jniLibs.srcDirs = [‘libs’]
aidl.srcDirs = [‘src/main/java’]
}
}
关于怎样在 AndroidStudio 中引用 aidl 文件的,可以参考我的这一篇文章 AndroidStudio 引用 aidl 文件的两种方法
编写一个 Service,实现接口,处理客户端的请求,并将接口返回回去
public class EasyService extends Service {
private static final String TAG = “EasyService”;
public EasyService() {
}
IEasyService.Stub mIBinder=new IEasyService.Stub() {
@Override
public void connect(String mes) throws RemoteException {
LogUtil.i(TAG,“connect: mes =” + mes);
}
@Override
public void disConnect(String mes) throws RemoteException {
LogUtil.i(TAG, “disConnect: mes =” +mes);
}
};
@Override
public IBinder onBind(Intent intent) {
LogUtil.i(TAG,"onBind: intent = "+intent.toString());
return mIBinder;
}
@Override
public boolean onUnbind(Intent intent) {
LogUtil.i(TAG,“onUnbind: =”);
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
LogUtil.i(TAG,“onDestroy: =”);
super.onDestroy();
}
}
这个 Service 所做的动作就是当客户端连接上的时候,会启动我们的 Service,此时会调用 Service 的 onBInd 方法,在 onBinder 方法里面,我们将 mIBinder (实现了 IEasyService.Stub 接口)返回回去。他充当客户端和服务端的桥梁,通过他我们可以进行通讯。
至于这个 IEasyService.Stub 是什么呢?其实当我们在 AndroidStudio 里面编写完 aidl 文件,重新 make project 一下,就会自动生成了。
将服务端的 Service 暴露出去
在 AndroidManifest 文件下,配置 Service 的 action 及 exported 等信息。
其中 android:exported=“true” 表示别的进程可以访问,这个是必须配置的。android:process=“:remote” 表示运行在 :remote 进程,不配置的话默认运行所在的 App 进程,这个可以不配置。
<service
android:name=“.easy.EasyService”
android:enabled=“true”
android:exported=“true”
android:process=“:remote”>
-
将服务端的 aidl 文件 copy 过来,注意要放在同一个包下。
-
通过服务端 Service 的 Action 启动, 当启动 Service 成功的时候,将服务端返回的 Binder 保存下来并转化成相应的实例。
-
之后如果想与服务端通讯,通过保存下来的 Binder,即可调用服务端的方法。
第一步:将服务端的 aidl 文件 copy 过来,注意要放在同一个包下
- 第二步,通过服务端 Service 的 Action 启动, 当启动 Service 成功的时候,将服务端返回的 Binder 保存下来并转化成相应的实例
当我们点击按钮的时候,我们通过 Action 去启动远程 servic。
case R.id.btn_start_service:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
- 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
带来很多收获:**
[外链图片转存中…(img-lcKm6jAL-1713710964769)]
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
- 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!