腾讯Android研发岗必刷真题:说下组件之间的跳转和组件通信原理机制

  • String methodName
  • Object methodClass
    */
    private static ArrayMap<Class<?>,ArrayMap<String,ArrayList>> moduleMethodClient = new ArrayMap<>();

在使用方法上,在onCreate()和onDestroy()中需要注册和解绑,比如

ModuleBus.getInstance().register(this);
ModuleBus.getInstance().unregister(this);

最终使用类似EventBus 中 post 方法一样,进行两个组件间的通信。这个框架的封装的post 方法如下

public void post(Class<?> clientClass,String methodName,Object…args){
if(clientClass == null || methodName == null ||methodName.length() == 0) return;

ArrayList clientList = getClient(clientClass,methodName);

if(clientList == null) return;

try{
for(Object c: clientList){
try{
ArrayMap<String,MethodInfo> methods = moduleEventMethods.get©;
Method method = methods.get(methodName).m;
if(method == null){
Log.e(TAG,“cannot find client method”+methodName +“for args[”+args.length+“]” + Arrays.toString(args));
return;
}else if(method.getParameterTypes() == null){
Log.e(TAG,“cannot find client method param:”+method.getParameterTypes() +“for args[”+args.length+“]” + Arrays.toString(args));
return;
}else if(method.getParameterTypes().length != args.length){
Log.e(TAG,“method “+methodName +” param number not matched:method(”+method.getParameterTypes().length+“), args(” + args.length+“)”);
return;
}
method.invoke(c,args);
}catch (Throwable e){
Log.e(TAG,“Notifiy client method invoke error.”,e);
}
}

}catch (Throwable e){
Log.e(TAG,“Notify client error”,e);
}
}

可以看到,它是通过遍历之前内部的ArrayMap,把注册在里面的方法找出,根据传入的参数进行匹配,使用反射调用。

接口+路由

接口+路由实现方式则相对容易理解点,我之前实践的一个项目就是通过这种方式实现的。具体地址如下:DemoComponent 实现思路是专门抽取一个LibModule作为路由服务,每个组件声明自己提供的服务 Service API,这些 Service 都是一些接口,组件负责将这些 Service 实现并注册到一个统一的路由 Router 中去,如果要使用某个组件的功能,只需要向Router 请求这个 Service 的实现,具体的实现细节我们全然不关心,只要能返回我们需要的结果就可以了。

比如定义两个路由地址,一个登陆组件,一个设置组件,核心代码:

public class RouterPath {

//注意路由的命名,路径第一个开头需要不一致,保证唯一性
//Login Service
public static final String ROUTER_PATH_TO_LOGIN_SERVICE = “/login/service”;

//Setting Service
public static final String ROUTER_PATH_TO_SETTING_SERVICE = “/setting/service”;
}

那么就相应着就有两个接口API,如下:

public interface ILoginProvider extends IProvider {

void goToLogin(Activity activity);
}

public interface ISettingProvider extends IProvider {

void goToSetting(Activity activity);
}

这两个接口API对应着是向外暴露这两个组件的能提供的通信能力,然后每个组件对接口进行实现,如下:

@Route(path = RouterPath.ROUTER_PATH_TO_LOGIN_SERVICE, name = “登陆页面”)
public class LoginService implements ILoginProvider {
@Override
public void init(Context context) {}

@Override
public void goToLogin(Activity activity) {
Intent loginIntent = new Intent(activity, LoginActivity.class);
activity.startActivity(loginIntent);
}
}

这其中使用的到了阿里的ARouter页面跳转方式,内部本质也是接口+实现方式进行组件间通信。

调用则很简单了,如下:

ILoginProvider loginService = (ILoginProvider) ARouter.getInstance().build(RouterPath.ROUTER_PATH_TO_LOGIN_SERVICE).navigation();
if(loginService != null){
loginService.goToLogin(MainActivity.this);
}

还有一个组件化框架,就是ModularizationArchitecture ,它本质实现方式也是接口+实现,但是封装形式稍微不一样点,它是每个功能模块中需要使用注解建立Action事件,每个Action完成一个事件动作。invoke只是方法名为反射,并未用到反射,而是使用接口方式调用,参数是通过HashMap<String,String>传递的,无法传递对象。具体详解可以看这篇文章 Android架构思考(模块化、多进程)

页面跳转

页面跳转也算是一种组件间的通信,只不过它相对粒度更细化点,之前我们描述的组件间通信粒度会更抽象点,页面跳转则是定位到某个组件的某个页面,可能是某个Activity,或者某个Fragment,要跳转到另外一个组件的Activity或Fragment,是这两者之间的通信。甚至在一般没有进行组件化架构的工程项目中,往往也会封装页面之间的跳转代码类,往往也会有路由中心的概念。不过一般 UI 跳转基本都会单独处理,一般通过短链的方式来跳转到具体的 Activity。每个组件可以注册自己所能处理的短链的 Scheme 和 Host,并定义传输数据的格式,然后注册到统一的 UIRouter 中,UIRouter 通过 Scheme 和 Host 的匹配关系负责分发路由。但目前比较主流的做法是通过在每个 Activity 上添加注解,然后通过 APT 形成具体的逻辑代码。

下面简单介绍目前比较主流的两个框架核心实现思路:

ARouter

ARouter 核心实现思路是,我们在代码里加入的@Route注解,会在编译时期通过apt生成一些存储path和activityClass映射关系的类文件,然后app进程启动的时候会拿到这些类文件,把保存这些映射关系的数据读到内存里(保存在map里),然后在进行路由跳转的时候,通过build()方法传入要到达页面的路由地址,ARouter会通过它自己存储的路由表找到路由地址对应的Activity.class(activity.class = map.get(path)),然后new Intent(),当调用ARouter的withString()方法它的内部会调用intent.putExtra(String name, String value),调用navigation()方法,它的内部会调用startActivity(intent)进行跳转,这样便可以实现两个相互没有依赖的module顺利的启动对方的Activity了。

ActivityRouter

ActivityRouter 核心实现思路是,它是通过路由 + 静态方法来实现,在静态方法上加注解来暴露服务,但不支持返回值,且参数固定位(context, bundle),基于apt技术,通过注解方式来实现URL打开Activity功能,并支持在WebView和外部浏览器使用,支持多级Activity跳转,支持Bundle、Uri参数注入并转换参数类型。它实现相对简单点,也是比较早期比较流行的做法,不过学习它也是很有参考意义的。

小结

总的来说,组件间的通信机制在组件化编程和组件化架构中是很重要的一个环节,可能在每个组件独自开发阶段,不需要与其他组件进行通信,只需要在内部通信即可,当处于组件集成阶段,那就需要大量组件进行互相通信,体现在每个业务互相协作,如果组件间设计的不好,打开一个页面或调用一个方法,想当耗时或响应慢,那么体现的则是这个APP使用比较卡顿,仅仅打开一个页面就是需要好几秒才能打开,则严重影响使用者的体验了,甚至一些大型APP,可能组件分化更小,种类更多,那么组件间的通信则至关重要了。所以,要打造一个良好的组件化框架,如何设计一个更适合自己本身的业务类型的通信机制,就需要多多进行思考了。

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以加一下合作的技术群:185873940。来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

这里放上一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,在这里免费分享给大家,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~
加群:185873940 找管理员免费领取

未完待续。。。

这里只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢在关注一下~

分享读者

作者2013年java转到Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。

被人面试过,也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!

我们整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。

主要包括腾讯,以及字节跳动,阿里,华为,小米,等一线互联网公司主流架构技术。

腾讯T3架构师学习专题资料

如果你觉得自己学习效率低,缺乏正确的指导,可以一起学习交流!

我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
最重要的。

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值