首页 > 其他分享 >android Route模块化路由设计方案

android Route模块化路由设计方案

时间:2023-04-12 10:32:13浏览次数:42  
标签:String Route routeCode key 跳转 android Annotation 路由


背景:

我们在移动端开发过程,随着业务越来越多,越来越复杂,在架构中会将业务进行剥离和抽取,这样会出现许多业务模块。但是各业务模块又有业务关联,常见的就是Activity之间的跳转。但是,一些大的公司,或者业务线非常多的app大多数采用混合模式,

常见的就是H5和app混合,特别是电商商业比较常见。这时候H5通过连接跳转到原生,我们只需要知道原生页面的keyCode,就能和原生一样去访问原生业务。

问题:

在Activity之间跳转,我们可以用Intent现有的显示和隐式跳转,如果在相同模块类跳转很方便,在不同模块中就要需要知道目标Activity的className,如果别人改变类型或者类的文件路径,就会导致其他模块无法访问到。

如果我们把Activity和对应的key进行绑定,通过绑定来跳转。这样就非常方便。

解决方案:

"路由",路由相当于Activity的门牌号引导系统,我只要知道门牌号,即使是瞎子,也能找到家,所以我们只要给Activity定义好唯一的routeCode,就能找到对应的页面。

路由的设计:

1.注解

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。

Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。

网上很多关于 Java Annotation 的文章,看得人眼花缭乱。Java Annotation 本来很简单的,结果说的人没说清楚;弄的看的人更加迷糊。

我按照自己的思路,对 Annotation 进行了整理。理解 Annotation 的关键,是理解 Annotation 的语法和用法,对这些内容,我都进行了详细说明;理解 Annotation 的语法和用法之后,再看 Annotation 的框架图,可能有更深刻体会。废话就说这么多,下面开始对 Annotation 进行说明。若您发现文章中存在错误或不足的地方,希望您能指出!

1.1、Annotation 架构

android Route模块化路由设计方案_bundle

1.2. ElementType 是 Enum 枚举类型,它用来指定 Annotation 的类型

public enum ElementType {
    TYPE,               /* 类、接口(包括注释类型)或枚举声明  */

    FIELD,              /* 字段声明(包括枚举常量)  */

    METHOD,             /* 方法声明  */

    PARAMETER,          /* 参数声明  */

    CONSTRUCTOR,        /* 构造方法声明  */

    LOCAL_VARIABLE,     /* 局部变量声明  */

    ANNOTATION_TYPE,    /* 注释类型声明  */

    PACKAGE             /* 包声明  */
}

1.3. RetentionPolicy 是 Enum 枚举类型,它用来指定 Annotation 的策略。通俗点说,就是不同 RetentionPolicy 类型的 Annotation 的作用域不同

"每 1 个 Annotation" 都与 "1 个 RetentionPolicy" 关联。

  • a) 若 Annotation 的类型为 SOURCE,则意味着:Annotation 仅存在于编译器处理期间,编译器处理完之后,该 Annotation 就没用了。 例如," @Override" 标志就是一个 Annotation。当它修饰一个方法的时候,就意味着该方法覆盖父类的方法;并且在编译期间会进行语法检查!编译器处理完后,"@Override" 就没有任何作用了。
  • b) 若 Annotation 的类型为 CLASS,则意味着:编译器将 Annotation 存储于类对应的 .class 文件中,它是 Annotation 的默认行为。
  • c) 若 Annotation 的类型为 RUNTIME,则意味着:编译器将 Annotation 存储于 class 文件中,并且可由JVM读入。

2.路由设计

Route

@Target(TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Route {
    String routeCode() default "";
}

Route注解:定义了作用于类上的,且申明了一个routeKey变量;

小试牛刀:

1.创建一个Activity并使用注解绑定一个routeKey:

@Route(routeCode = "1001")
public class RoueActivity1 extends Activity {


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

2.创建一个路由管理工具:RouteManager

2.1获取当前包下,直接注解Route所关联的Activity,证明这些类都支持路由,并存储起来(一般这个方法在application中初始化)

public void initAppPackRouteActivity() {
    PackageManager manager = mContext.getPackageManager();
    try {
        PackageInfo packageInfo = manager.getPackageInfo(
                mContext.getPackageName(), PackageManager.GET_ACTIVITIES);

        if (packageInfo != null) {
            for (ActivityInfo info : packageInfo.activities) {
                String className = info.name;
                Class<?> cls = Class.forName(className);
                Route route = cls.getAnnotation(Route.class);
                if (route != null && !TextUtils.isEmpty(route.className())) {
                    RouteActivityBean bean = new RouteActivityBean(route.routeCode(), route.className());
                    routeActivityBeans.add(bean);
                   
                }


            }
        }

    } catch (Exception e) {

    }
}

2.2 路由的使用

     1.路由的使用(原生之间的跳转)

public void routeDetail(String code, Bundle bundle) {

    for (RouteActivityBean bean : routeActivityBeans) {
        if (TextUtils.equals(code, bean.getRouteCode())) {
          //找到路由key,进行跳转
            Intent intent = new Intent();
            intent.setClassName(mContext.getPackageName(), bean.getActivityName());
            intent.putExtras(bundle);
            mContext.startActivity(intent);
            break;
        }
    }

}

 2.H5访问原生页面

public void routeDetail(String routeUrl) {
   //routeCode是html中routeKye的key
    if (routeUrl.contains(routeCode) && routeUrl.contains("?")) {

        String[] text = routeUrl.split("\\?");
        String[] keyValue = text[1].split("&");
        Bundle bundle = new Bundle();
        String routeCode = "";//获取路由编号
        for (String value : keyValue) {
            if (TextUtils.isEmpty(value)) {
                continue;
            }
            String[] kv = value.split("=");
            String key = "";
            String keyByValue = "";
            if (kv.length == 1) {
                key = kv[0];

            } else if (kv.length == 2) {
                key = kv[0];
                keyByValue = kv[1];
            }
            if (TextUtils.isEmpty(key)) {
                continue;
            }
            if (TextUtils.equals(routeCode, key)) {
                //key
                routeCode = keyByValue;
            } else {
                bundle.putString(key, keyByValue);
            }


        }
        routeDetail(routeCode, bundle);//转换成原生,访问原生页面

    } else {
        //默认走内置h5,的页面,自己配置,如果没有路由标识,业务自行处理

    }


}

3.如何使用。

 3.1原生:

Bundle bundle=new Bundle();

bundle.putString("name","nihao");

routeDetail("1001",bundle);

3.2 H5使用:

先定义一个路由关键字:routeCode;

public static String h5="www.123.com?routeCode=1001&name=nihao";

routeDetail(h5);

如果定义的1001路由存在,就会找到对应的页面,跳转过去,在原生页面正常解析即可。

依赖库:implementation 'com.github.it90msart:LBRoute:1.0.0'

github项目地址:https://github.com/it90msart/LBRoute

总结:路由设计并不繁琐,但是在开发过程中使用好,可以很好的解耦,提升效率,提升组件化开发。也便于module业务间的维护。

代码GIT地址:

https://github.com/it90msart/LBRoutehttps://github.com/it90msart/LBRoute

集成依赖库: 依赖库implementation 'com.github.it90msart:LBRoute:1.0.0'

标签:String,Route,routeCode,key,跳转,android,Annotation,路由
From: https://blog.51cto.com/u_16065093/6185193

相关文章

  • Android Kotlin实战之高阶使用泛型扩展协程懒加载详解
    前言:通过前面几篇文章,我们已基本掌握kotlin的基本写法与使用,但是在开发过程中,以及一些开源的API还是会出现大家模式的高阶玩法以及问题,如何避免,接下来讲解针对原来的文章进行一些扩展,解决大家在工作中遇到的问题,如何去解决如果还有人不了解kotlin,可以查看我的基础篇kotlin。Android......
  • android监听耳机按键
    app在前台的监听方式:@OverridebooleanonKeyDown(intkeyCode,KeyEventevent){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){returnsuper.onKeyDown(keyCode,event);}switch(keyCode){caseKeyE......
  • Chrome模拟手机浏览器(iOS/Android)的方法
    1、在chrome的开发者工具模式下,点击左上角的手机图标切换成手机模式(或者F12然后Ctrl+Shift+M),一般这个方法访问绝大多数设限的网站。2、第一种方法不行,则安装Google插件User-AgentSwitcherforGoogleChrome3、https://blog.csdn.net/gb4215287/article/details/64438603......
  • m基于GA遗传优化和OSPF协议的WSN最短路由算法matlab仿真,并输出节点的不同层域
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要2.1GA遗传优化        GA把问题的解表示成“染色体”,在算法中也即是以二进制编码的串。并且,在执行遗传算法之前,给出一群“染色体”,也即是假设解。然后,把这些假设解置于问题的“环境”中,并按......
  • Android脱壳基础知识
    JVM的类加载器:BootstrapClassLoader引导类加载器:C/C++代码实现的加载器,用于加载制定的JDK核心库,比如java.lang.*、java.util.*等这些系统类。Java虚拟机的启动就是通过Bootstrap,该ClassLoader在java里无法获取,负责加载/lib下的类ExtensionsClassLoader拓展类加载器:Java中的......
  • Android-APK反编译
    1.原理学习反编译之前,建议先学习一下Apk打包的过程,明白打包完成后的Apk里面都有什么文件,各种文件都是怎么生成的。Apk技术也有非常多的技术可以学习,主要都是围绕着如何减小体积,如何提高打包速度展开,这里先不多说了。下面是一张基本的Apk文件结构图。Apk文件本质上其实是一个zip......
  • Android - AXMLPrinter2.jar的使用方法
    我们需要查看打出的apk包中AndroidManifest.xml文件,但是打开之后发现是一大堆的乱码这是就需要反编译工具,AXMLPrinter2.jarAXMLPrinter2.jar官方介绍:AXMLPrinter2.jarapk分析APK文件,取得APK文件中的包名、版本号及图标,很强大的工具,再一次感受到了批处理的牛逼。可以将android......
  • N1设置旁路由
              天灵大佬r2s固件:https://wws.lanzoux.com/iBzoNnd2ntaflippy大佬N1固件:https://www.right.com.cn/forum/thread...N1防火墙规则:iptables-tnat-IPOSTROUTING-oeth0-jMASQUERADEr2s防火墙规则:iptables-tnat-IPOSTROUTING-jMASQUE......
  • 成品直播源码,Android实现监听Settings值变化的功能
    成品直播源码,Android实现监听Settings值变化的功能先创建一个内部类继承自ContentObserver   classSettingsContentObserverextendsContentObserver{    publicSettingsContentObserver(){      super(newHandler());    }    ......
  • 路由跳转及传参
    meta字段:路由元信息路由跳转有几种方式:A->B1.声明式导航:router-link(务必要有to属性),可以实现路由的跳转。2.编程式导航:利用的是组件实例得$router.push|replace方法,可以实现路由的跳转。(可以书写一些自己的业务) params参数:keyword  , query参数:k路由传参,参数的写法:......