这是一个在安卓平台上运行的ipc的库,让ipc通信更加简单。它具有以下特点:
- 支持自定义接口来实现跨进程通信,比传统的aidl的方式更简单
- 支持异步回调的方式返回数据,也支持设置监听器的方式
- 服务注册支持自动注册
- 突破binder驱动限制,支持大数据传输(已支持到最新版本Android14)
**1.**添加jitpack仓库到工程当中
allprojects {
repositories {
...
maven { url 'https://www.jitpack.io' }
}
}
**2.**添加依赖
dependencies {
implementation 'com.github.zhanggaoming.android-ipc:ipc-core:3.1.1'
}
@BindImpl("com.demo.ipc.InfoServiceManager")
interface InfoService {
fun asyncGetUserInfo(callBack: Result<UserInfo>)
fun syncGetUserInfo(): UserInfo
fun sum(a: Int, b: Int, c: Int, result: Result<Int>)
fun sendBigData(@BigData data: ByteArray)
fun getEnum(code: Code): Code
fun setEventCallBack(callBack: Result<Event>)
}
enum class Code {
SUCCESS, FAILURE
}
data class Event(val id: Int)
data class UserInfo(val name: String, val age: Int)
上述接口定义支持回调的方式,定义回调的接口返回,必须使用Result类来承载
首先服务端进程需要声明在AndroidManifest.xml里面注册两个service:
<service android:name="com.zclever.ipc.core.server.VideoCenter" android:exported="true"/>
<service android:name="com.zclever.ipc.core.server.ServiceCenter" android:exported="true"/>
服务端实现上述接口,kotlin代码需要是object类:
object InfoServiceManager : InfoService {
//获取userInfo,走的是回调的方式
override fun asyncGetUserInfo(callBack: Result<UserInfo>) {
thread {
callBack.onData(UserInfo("asyncGetUserInfo", 20))
}
}
override fun syncGetUserInfo(): UserInfo {
return UserInfo("syncGetUserInfo", 18)
}
override fun sum(a: Int, b: Int, c: Int, result: Result<Int>) {
result.onData(a + b + c)
}
override fun sendBigData(data: ByteArray) {
Log.i(TAG, "sendBigData: ${data.contentToString()}")
}
override fun getEnum(code: Code): Code {
Log.i(TAG, "getEnum: $code")
return Code.SUCCESS
}
private var count=0
private var mCallBack: Result<Event>? = null
init {
thread {//模拟回调事件回复客户端
while (true) {
mCallBack?.onData(Event(count++))
Thread.sleep(2000)
}
}
}
override fun setEventCallBack(callBack: Result<Event>) {
mCallBack = callBack
}
}
java代码必须要写getInstance方法,返回自身,使用单例模式:
public class InfoServiceManagerJava implements InfoService {
private static final String TAG = "InfoServiceManagerJava";
@Override
public void sum(int a, int b, int c, @NotNull Result<Integer> result) {
result.onData(a + b + c);
}
@Override
public void sendBigData(@NotNull byte[] data) {
Log.i(TAG, "sendBigData: " + Arrays.toString(data));
}
@NotNull
@Override
public Code getEnum(Code code) {
return Code.SUCCESS;
}
@Override
public void setEventCallBack(@NotNull Result<Event> callBack) {
}
private static final class Holder {
private static final InfoServiceManagerJava instance = new InfoServiceManagerJava();
}
private InfoServiceManagerJava() {
}
public static InfoServiceManagerJava getInstance() {
return Holder.instance;
}
@Override
public void asyncGetUserInfo(@NotNull Result<UserInfo> callBack) {
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
callBack.onData(new UserInfo("asyncGetUserInfo", 24));
}
});
}
@NotNull
@Override
public UserInfo syncGetUserInfo() {
return new UserInfo("syncGetUserInfo", 18);
}
}
服务端需要把服务注册到IpcManager当中,这里支持手动和自动注册:
- 手动注册,通过IpcManager注册,手动注册要提前,建议是在Application当中注册:
IpcManager.register(InfoService::class) //注册服务
- 自动注册,通过注解处理器来处理,在module中引入ipc-compiler模块:
plugins {
...
id 'kotlin-kapt'
}
或者
applay plugin:'kotlin-kapt'
dependencies {
...
kapt 'com.github.zhanggaoming.android-ipc:ipc-compiler:3.1.1'
}
引入ipc-compiler模块后,会自动找BindImpl注解修饰的接口并注册到IpcManager当中
客户端进程主要就是使用IpcManager这个类来寻找服务:
**1.**初始化并连接服务端进程:
IpcManager.init(this)//传入上下文
IpcManager.open("com.demo.ipcdemo")//连接服务端,传入的是服务端的包名
**2.**发现服务:
kotlin
IpcManager.getService(InfoService::class)
IpcManager.getService<InfoService>()
java
IpcManager.INSTANCE.getService(InfoService.class);
以下是客户端demo的主要代码:
class CommonActivity : AppCompatActivity() {
companion object {
private const val TAG = "CommonActivity"
}
val instance by lazy { IpcManager.getService<InfoService>() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_common)
IpcManager.config(Config.builder().configDebug(true).build())
IpcManager.init(this)
IpcManager.open("com.demo.ipcdemo")
}
fun syncGetUserInfo(view: View) {
Toast.makeText(this, instance.syncGetUserInfo().toString(), Toast.LENGTH_LONG).show()
Log.i(TAG, "syncGetUserInfo: ->${instance.getEnum(Code.FAILURE)}")
}
fun asyncGetUserInfo(view: View) {
instance.asyncGetUserInfo(object : Result<UserInfo>() {
override fun onData(data: UserInfo) {
runOnUiThread {
Toast.makeText(this@CommonActivity, data.toString(), Toast.LENGTH_LONG).show()
}
}
})
}
fun sum(view: View) {
instance.sum(1, 2, 3, object : Result<Int>() {
override fun onData(data: Int) {
runOnUiThread {
Toast.makeText(this@CommonActivity, "the sum is $data", Toast.LENGTH_LONG)
.show()
}
}
})
}
fun sendBigData(view: View) {
instance.sendBigData(byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
}
fun setEventCallBack(view: View) {
instance.setEventCallBack(object : Result<Event>() {
override fun onData(data: Event) {
Log.i(TAG, "onData: ${data.id}")
}
})
}
}
想要详细了解如何使用请参考demo:
https://github.com/zhanggaoming/android-ipc/tree/master/ipc-app-test