前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >arouter实现activity跳转原理

arouter实现activity跳转原理

作者头像
全栈程序员站长
发布于 2022-08-31 07:40:32
发布于 2022-08-31 07:40:32
51500
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

一、思路分析

arouter让我们可以非常简单地实现组件间页面跳转,实现的基本思路是

1. 在对应的activity上加上注解,通过apt技术来自动生成代码,代码能将 activity对应路径 和 class 添加到路由表中;

2. 通过扫描获取所有类,遍历自动执行步骤1中所生成地代码,从而路由表中有了对应地数据,路由表的数据结构为 Map<String,Class<? extends Activity>> routes;

3. 进行跳转时,通过路径可在路由表中找到对应的acitivity,从而实现跳转

二、源码分析

1. 注解

注解编译中,利用自定义注解 @Route 设置路径,在RouteProcessor的process方法中生成代码,代码中可将对应的路径、目标activity添加到路由表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//Route.java 自定义注解Route
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {
    String path();
    String group() default "";
    String name() default "";
   int extras() default Integer.MIN_VALUE;
   int priority() default -1;
}

//RouteProcessor.java 注解处理器
public class RouteProcessor extends AbstractProcessor {
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (CollectionUtils.isNotEmpty(annotations)) {
            //获取 Route注解的所有节点
            Set<? extends Element> routeElements = roundEnv.getElementsAnnotatedWith(Route.class);
            try {
                logger.info(">>> Found routes, start... <<<");
                //处理节点
                this.parseRoutes(routeElements);

            } catch (Exception e) {
                logger.error(e);
            }
            return true;
        }

        return false;
    }

    private void parseRoutes(Set<? extends Element> routeElements) throws IOException {
        ...
                    //生成路由表内容
                    loadIntoMethodOfGroupBuilder.addStatement(
                            "atlas.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, " + (StringUtils.isEmpty(mapBody) ? null : ("new java.util.HashMap<String, Integer>(){
  
  {" + mapBodyBuilder.toString() + "}}")) + ", " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))",
                            routeMeta.getPath(),
                            routeMetaCn,
                            routeTypeCn,
                            className,
                            routeMeta.getPath().toLowerCase(),
                            routeMeta.getGroup().toLowerCase());

                    routeDoc.setClassName(className.toString());
                    routeDocList.add(routeDoc);
                }

                // Generate groups
                String groupFileName = NAME_OF_GROUP + groupName;
                JavaFile.builder(PACKAGE_OF_GENERATE_FILE,
                        TypeSpec.classBuilder(groupFileName)
                                .addJavadoc(WARNING_TIPS)
                                .addSuperinterface(ClassName.get(type_IRouteGroup))
                                .addModifiers(PUBLIC)
                                .addMethod(loadIntoMethodOfGroupBuilder.build())
                                .build()
                ).build().writeTo(mFiler);

                logger.info(">>> Generated group: " + groupName + "<<<");
                rootMap.put(groupName, groupFileName);
                docSource.put(groupName, routeDocList);
            }

          ...

            // 将含有路由表内容的java文件存到磁盘中
            String rootFileName = NAME_OF_ROOT + SEPARATOR + moduleName;
            JavaFile.builder(PACKAGE_OF_GENERATE_FILE,
                    TypeSpec.classBuilder(rootFileName)
                            .addJavadoc(WARNING_TIPS)
                            .addSuperinterface(ClassName.get(elements.getTypeElement(ITROUTE_ROOT)))
                            .addModifiers(PUBLIC)
                            .addMethod(loadIntoMethodOfRootBuilder.build())
                            .build()
            ).build().writeTo(mFiler);

        }
    }
}

上述实现了在编译期生成路由表,生成的路由表在app/build/intermediates/classes/包名/routes下,自动生成的代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ARouter$$Group$$test implements IRouteGroup {
    atlas.put("/test/activity2", RouteMeta.build(RouteType.ACTIVITY, Test2Activity.class, "/test/activity2", "test", new HashMap<String, Integer>() {
            {
                this.put("key1", 8);
            }
        }, -1, -2147483648));
        atlas.put("/test/activity3", RouteMeta.build(RouteType.ACTIVITY, Test3Activity.class, "/test/activity3", "test", new HashMap<String, Integer>() {
            {
                this.put("name", 8);
                this.put("boy", 0);
                this.put("age", 3);
            }
        }, -1, -2147483648));
}

2. 扫描获取所有类

步骤1中生成的代码并不会自动执行,所以需要通过扫描获取所有class,遍历执行添加到路由表的方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//LogisticsCenter.java
public synchronized static void init(Context context, ThreadPoolExecutor tpe){
    //通过扫描获取到所有满足要求的class
    routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);
    for (String className : routerMap) {
        //执行添加到路由表的方法
        ((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
    }
}

3. 跳转

有了路由表,跳转时,通过传入目标activity路径,arouter会根据路径从路由表中找到目标activity,然后将目标activity设置到intent上,再通过startActivity来实现跳转。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//_ARouter.java
private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        final Context currentContext = null == context ? mContext : context;

        switch (postcard.getType()) {
            case ACTIVITY:
                // 构建intent,设置目标activity,postcard.getDestination()即 XxxActivity.class
                final Intent intent = new Intent(currentContext, postcard.getDestination());
                intent.putExtras(postcard.getExtras());

                // 设置flag
                int flags = postcard.getFlags();
                if (-1 != flags) {
                    intent.setFlags(flags);
                } else if (!(currentContext instanceof Activity)) {    // Non activity, need less one flag.
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                }

                // Set Actions
                String action = postcard.getAction();
                if (!TextUtils.isEmpty(action)) {
                    intent.setAction(action);
                }

                // 在主线程中执行跳转操作
                runInMainThread(new Runnable() {
                    @Override
                    public void run() {
                        //通过startActivity来实现跳转
                        startActivity(requestCode, currentContext, intent, postcard, callback);
                    }
                });

                break;
            ...
        }

        return null;
    }

Postcard类中包含了利用@Route注解配置的路径、携带参数、action、目标activity(即destination)等,把postcard中的参数设置到intent上,然后通过startActivity来进行跳转。

如需了解更多请点击

java注解编译学习

arouter原理官方文档

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/143535.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
阿里ARouter使用及源码解析(一)
在app的开发中,页面之间的相互跳转是最基本常用的功能。在Android中的跳转一般通过显式intent和隐式intent两种方式实现的,而Android的原生跳转方式会存在一些缺点:
用户3106371
2018/09/12
1.4K0
阿里ARouter使用及源码解析(一)
“终于懂了” 系列:组件化框架 ARouter 完全解析(一) 原理详解
在我之前的组件化文章《“终于懂了” 系列:Android组件化,全面掌握!》中,提到为了实现组件化要解决的几个问题点,其中 页面跳转、组件间通信 的问题是使用了 ARouter 这个框架来解决的。ARouter确实是专门用于做组件化改造,官方是这么介绍的:
胡飞洋
2022/11/08
3.3K0
“终于懂了” 系列:组件化框架 ARouter 完全解析(一) 原理详解
ARouter源码解析(一)前言ARouter 源码番外
之前对 ActivityRouter 的源码做了一次分析,相信大家对路由框架已经有一个大概的理解了。
俞其荣
2019/01/03
8170
【Android 组件化】使用 ARoute 实现组件化 ( ARoute 初始化 及 界面跳转 源码分析 )
引入了 ARoute 的应用 , 一般会在主应用的 Application 中的 onCreate 方法中初始化 ARoute ;
韩曙亮
2023/03/29
1.2K0
【Android 组件化】使用 ARoute 实现组件化 ( ARoute 初始化 及 界面跳转 源码分析 )
Android项目解耦--路由框架ARouter源码解析
上一篇文章Android项目解耦--路由框架ARouter的使用讲述了ARouter在项目中的使用,这边文章主要对ARouter的源码进行学习和分析。
静默加载
2020/05/29
1.1K0
ARouter路由记录
网上关于 ARouter 源码解析的文章已经不少了,这里简单总结一下自己的理解,方便以后查看和复习
木子杂志
2020/08/04
5640
ARouter路由记录
ARouter源码解析(四)
之前对 arouter-api 做了整个流程的分析,今天来看看 arouter-compiler 。
俞其荣
2019/02/15
7760
深入探究 ARouter
我们只关注重点,LogisticsCenter.init(mContext, executor);,executor是一个线程池。
大发明家
2022/01/15
8150
一图抵千言《ARouter简明扼要原理分析》
这段代码最终会利用当前类名和规则,拼接成KotlinTestActivity$$ARouter$$Autowired的全类名,然后利用反射传进对象。然后执行inject(this); 然后里面会初始化传输字段序列化服务,然后强转target,开始赋值数据
g小志
2022/03/29
7610
一图抵千言《ARouter简明扼要原理分析》
“终于懂了” 系列:组件化框架 ARouter 完全解析(二)APT技术
在上一篇《“终于懂了” 系列:组件化框架 ARouter 完全解析(一) 原理详解》中,详细介绍了ARouter的核心原理。其中提到了“帮助类”的概念,也就是在运行时生成 用于帮助填充WareHouse路由元信息的类,这里就涉及到了APT技术。那么本篇就对这一技术点进行介绍,并详细分析ARouter中是如何使用APT来生成帮助类的。
胡飞洋
2022/11/08
1.8K0
“终于懂了” 系列:组件化框架 ARouter 完全解析(二)APT技术
编译时注解(三)Arouter源码讲解
项目中我们有时需要跨模块startActivity,但是这样需要配置menifest,不方便。这时就需要阿里的一个路由框架Arouter Arouter的使用就不再多说了。这篇文章主要讲解他的源码
提莫队长
2019/02/21
6790
APP路由框架与组件化简析
前端开发经常遇到一个词:路由,在Android APP开发中,路由还经常和组件化开发强关联在一起,那么到底什么是路由,一个路由框架到底应该具备什么功能,实现原理是什么样的?路由是否是APP的强需求呢?与组件化到底什么关系,本文就简单分析下如上几个问题。
看书的小蜗牛
2021/06/21
8480
APP路由框架与组件化简析
ARouter三问—腾讯真题
为了项目解耦,实现模块的独立化,出现了组件化,而组件化中用作模块间通信的重要使者就是ARouter,今天就一起来看看这个神奇的工具。
码上积木
2020/10/29
1.4K0
【Android 组件化】路由组件 ( 生成 Root 类记录模块中的路由表 )
注解处理器 为每个 Module 模块生成一个路由表 , 该模块下凡是被 @Route 标注的路由节点都在该路由表中维护 ;
韩曙亮
2023/03/29
2.6K0
【Android 组件化】路由组件 ( 生成 Root 类记录模块中的路由表 )
Android组件化专题 - 路由框架原理
在路由框架之前,我们先了解什么是APT,并实践ButterKnife绑定findById的小功能。为什么先要讲解apt,因为路由的实现apt是核心的代码.看下面链接 APT 实践。
用户3045442
2018/09/11
1.7K0
Android组件化专题 - 路由框架原理
网易考拉Android客户端路由总线设计
当前,Android路由框架已经有很多了,如雨后春笋般出现,大概是因为去年提出了Android组件化的概念。当一个产品的业务规模上升到一定程度,或者是跨团队开发时,团队/模块间的合作问题就会暴露出来。如何保持团队间业务的往来?如何互不影响或干涉对方的开发进度?如何调用业务方的功能?组件化给上述问题提供了一个答案。组件化所要解决的核心问题是解耦,路由正是为了解决模块间的解耦而出现的。本文阐述了考拉Android端的路由设计方案,尽管与市面上的方案大同小异,但更多的倾向于与考拉业务进行一定程度的结合。
用户1269200
2018/12/21
1.3K0
ARouter 使用教程
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/81036719
程序员徐公
2018/09/17
2K0
ARouter 使用教程
Android项目解耦--路由框架ARouter的使用
随着业务量的增长,客户端必然随之越来越业务和功能模块耦合越来越生,开发人员代码维护成本越来越高。 App一般都会走向组件化、插件化的道路,而组件化、插件化的前提就是解耦,那么我们首先要做的就是解耦页面之间的依赖关系。
静默加载
2020/05/29
2.2K0
Android技术栈(二)组件化改造
国内都比较流行开发超级APP,也就是我全都要,什么功能都想加进去,这导致业务逻辑变得越来越复杂.
Android技术干货分享
2019/03/27
5340
Android技术栈(二)组件化改造
Android 组件化(二)注解与注解处理器、组件通讯
  在上一篇文章中,我们完成了组件的创建、gradle统一管理、组件模式管理和切换,那么这一篇文章,我们需要做的就是组件之间的通讯了。
晨曦_LLW
2022/11/21
6940
Android 组件化(二)注解与注解处理器、组件通讯
推荐阅读
相关推荐
阿里ARouter使用及源码解析(一)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档