当前位置:   article > 正文

android进程通信6,[Android]你不知道的Android进程化(6)--进程通信Andromeda框架

iqiyi andromeda

近来看到爱奇艺发布了多进程的架构框架Andromeda。研究一下其多进程的通信方式。

具体github地址

通过此框架的初步分析

1.通过grade插件完善AndroidManifest.xml配置文件

2.通过ContentProvider传输binder对象

3.活动binder.stub对象

4.动态绑定进程service以及binder对象

5.多进程binder管理

其在利用自定义Gradle插件来插入DispatchService和DipatchProvider。

自定义的Gradle插件只会有app module上运行。

其会读取Manifest里面的内容并进行修改。

f24809efdb7844c61d33e1be1126ac8b.png

插件配置.png

1.查找遍历Manifest文件

void injectStubServiceToManifest(Project project) {

println "injectStubServiceToManifest"

//主目录

rootDirPath = project.rootDir.absolutePath

def android = project.extensions.getByType(AppExtension)

this.dispatcher = project.extensions.getByType(DispatcherExtension)

project.afterEvaluate {

android.applicationVariants.all { variant ->

if (pkgName == null) {

//获取包名

pkgName = getPackageName(variant)

println "pkgName:" + pkgName

}

//查找遍历Mainfest文件

variant.outputs.each { output ->

output.processManifest.doLast {

println "manifestOutputDirectory:" + output.processManifest.manifestOutputDirectory.absolutePath

//output.getProcessManifest().manifestOutputDirectory

output.processManifest.outputs.files.each { File file ->

//在gradle plugin 3.0.0之前,file是文件,且文件名为AndroidManifest.xml

//在gradle plugin 3.0.0之后,file是目录,且不包含AndroidManifest.xml,需要自己拼接

//除了目录和AndroidManifest.xml之外,还可能会包含manifest-merger-debug-report.txt等不相干的文件,过滤它

if ((file.name.equalsIgnoreCase("AndroidManifest.xml") && !file.isDirectory()) || file.isDirectory()) {

if (file.isDirectory()) {

//3.0.0之后,自己拼接AndroidManifest.xml

injectManifestFile(new File(file, "AndroidManifest.xml"))

} else {

//3.0.0之前,直接使用

injectManifestFile(file)

}

}

}

}

}

}

}

}

其内会写入三种文件

def static final STUB_SERVICE = 'org.qiyi.video.svg.stub.CommuStubService$CommuStubService'

xml.application {

int index = 0

//每个进程都声明使用这个CommuStubService文件

customProcessNames.each {

//加上序号,$CommuStuService会替换成数字

String serviceName = "${STUB_SERVICE}" + index.toString()

service("${NAME}": serviceName,

"${ENABLED}": "${TRUE}",

"${EXPORTED}": "${FALSE}",

"${PROCESS}": it

)

if (matchedServices == null) {

matchedServices = new HashMap<>()

}

matchedServices.put(it, serviceName)

++index

}

这里DipatcherService和DipatchProvider是binder的中转管理控件,默认配置到主进程。

//配置进程地址

this.dispatcher = project.extensions.getByType(DispatcherExtension)

//之后,写入DispatcherService和DispatcherProvider

def dispatcherProcess = dispatcher.process

println "dispatcher.process:" + dispatcher.process

if (dispatcherProcess != null && dispatcherProcess.length() > 0) {

service("${NAME}": DISPATCHER_SERVICE,

"${ENABLED}": "${TRUE}",

"${EXPORTED}": "${FALSE}",

"${PROCESS}": dispatcherProcess

)

provider(

"${AUTHORITIES}": getAuthority(),

"${EXPORTED}": "${FALSE}",

"${NAME}": DISPTACHER_PROVIDER,

"${ENABLED}": "${TRUE}",

"${PROCESS}": dispatcherProcess

)

} else {

service("${NAME}": DISPATCHER_SERVICE,

"${ENABLED}": "${TRUE}",

"${EXPORTED}": "${FALSE}"

)

provider(

"${AUTHORITIES}": getAuthority(),

"${EXPORTED}": "${FALSE}",

"${NAME}": DISPTACHER_PROVIDER,

"${ENABLED}": "${TRUE}"

)

}

正如通信所涉及的必要的几个步骤

1.注册

2.发其通信

3.binder间的相互绑定

4.binder间传输数据

d752b2b4c6ccf9856d7ddefbb57dc7ee.png

注册流程

首先注册,通过公共的Andromeda入口注册提供远程沟通的服务

Andromeda.getInstance().registerRemoteService(IBuyApple.class, BuyAppleImpl.getInstance());

//RemoteTransfer

public static void registerRemoteService(Class serviceClass, T stubBinder) {

if (null == serviceClass || null == stubBinder) {

return;

}

RemoteTransfer.getInstance().registerStubService(serviceClass.getCanonicalName(), stubBinder);

}

//RemoteServiceTransfer

public void registerStubServiceLocked(String serviceCanonicalName, IBinder stubBinder,

Context context, IDispatcher dispatcherProxy, IRemoteTransfer.Stub stub) {

stubBinderCache.put(serviceCanonicalName, stubBinder);

if (dispatcherProxy == null) {

BinderWrapper wrapper = new BinderWrapper(stub.asBinder());

Intent intent = new Intent(context, DispatcherService.class);

intent.setAction(Constants.DISPATCH_REGISTER_SERVICE_ACTION);

intent.putExtra(Constants.KEY_REMOTE_TRANSFER_WRAPPER, wrapper);

intent.putExtra(Constants.KEY_BUSINESS_BINDER_WRAPPER, new BinderWrapper(stubBinder));

intent.putExtra(Constants.KEY_SERVICE_NAME, serviceCanonicalName);

setProcessInfo(intent, context);

ServiceUtils.startServiceSafely(context, intent);

} else {

try {

dispatcherProxy.registerRemoteService(serviceCanonicalName,

ProcessUtils.getProcessName(context), stubBinder);

} catch (RemoteException ex) {

ex.printStackTrace();

}

}

}

启动Service注册到DispatcherService当中

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

if (intent == null) {

return super.onStartCommand(intent, flags, startId);

}

Logger.d("DispatcherService-->onStartCommand,action:" + intent.getAction());

if (Constants.DISPATCH_REGISTER_SERVICE_ACTION.equals(intent.getAction())) {

//注册远程服务

registerRemoteService(intent);

} else if (Constants.DISPATCH_UNREGISTER_SERVICE_ACTION.equals(intent.getAction())) {

//注销远程服务

unregisterRemoteService(intent);

} else if (Constants.DISPATCH_EVENT_ACTION.equals(intent.getAction())) {

//传递数据

publishEvent(intent);

}

return super.onStartCommand(intent, flags, startId);

}

private void registerRemoteService(Intent intent) {

BinderWrapper wrapper = intent.getParcelableExtra(Constants.KEY_REMOTE_TRANSFER_WRAPPER);

BinderWrapper businessWrapper = intent.getParcelableExtra(Constants.KEY_BUSINESS_BINDER_WRAPPER);

String serviceCanonicalName = intent.getStringExtra(Constants.KEY_SERVICE_NAME);

int pid = intent.getIntExtra(Constants.KEY_PID, -1);

String processName = intent.getStringExtra(Constants.KEY_PROCESS_NAME);

try {

if (TextUtils.isEmpty(serviceCanonicalName)) {

//注意:RemoteTransfer.sendRegisterInfo()时,serviceCanonicalName为null,这是正常的,此时主要目的是reigsterAndReverseRegister()

Logger.e("service canonical name is null");

} else {

//注册到分发器上管理

Dispatcher.getInstance().registerRemoteService(serviceCanonicalName,

processName, businessWrapper.getBinder());

}

} catch (RemoteException ex) {

ex.printStackTrace();

} finally {

if (wrapper != null) {

registerAndReverseRegister(pid, wrapper.getBinder());

}

}

}

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

闽ICP备14008679号