Android组件化开发之路由(一)

最近在公司做了一套组件化开发的工程,目前项目架构基本完成了,写完后觉得路由开发这块是可以记录下,如果有时间也会写一下其他的模块。废话不多说进入我们今天的主题-路由。

为什么要用路由

        路由主要是解决组件化开发中,多moudle的工程解耦问题,如果你是单moudle工程,那这个对你来讲确实没有用处。

        但如果你是多moudel工程,那不可避免的就有个问题moudle的相互引用,解决了这个问题,我们的多模块开发才有意义,不然就成了形式主义,表面看组件化开发,但实际模块间相互依赖很严重,无法抽离,解决模块的解耦我觉得主要是两个问题,一是:模块间的页面相互跳转;二是模块公共内容调用。第一个问题就可以使用路由来解决,另外一个可以使用对外暴露api的方式给其他模块调用(这个我们后面再讲)。

实现步骤

1、创建路由的注解类

XActivity,我们需要传一个唯一的path参数作为key值

@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface XActivity {
    String path();
}

2、使用AbstractProcessor生成代理类,存储路由的映射值

/**
 * 生成代理类,储存映射关系
 * @param activityList
 */
private void dealAnnotation(Set<? extends Element> activityList) throws IOException {
    try {
        String className = Config.ACTIVITY_CLASS_NAME + Config.SEPARATOR + mMoudelName;
        String fieldName = "list";
        mMessager.printMessage(Diagnostic.Kind.NOTE,"className is:" + className);
        ClassName stringClass = ClassName.get(String.class);
        ParameterizedTypeName parameterizedTypeName = ParameterizedTypeName.get(ClassName.get(HashMap.class), stringClass, stringClass);

        //成员变量
        FieldSpec fieldSpec = FieldSpec.builder(parameterizedTypeName,fieldName,Modifier.PRIVATE).build();
        //构造方法
        MethodSpec.Builder constructor = MethodSpec.constructorBuilder()
                .addModifiers(Modifier.PUBLIC)
                .addStatement("$N = new HashMap<String,String>()", fieldSpec);
        for (Element element : activityList) {
            XActivity annotation = element.getAnnotation(XActivity.class);
            String path = annotation.path();
            String originClassName = element.asType().toString();//完成类名,后续用户activity跳转
            mMessager.printMessage(Diagnostic.Kind.NOTE,"originClassName is:" + originClassName);
            constructor.addStatement("$N.put($S,$S)",fieldSpec,path,originClassName);//将映射关系存进去
        }
        //创建获取映射集合方法
        MethodSpec methodSpec = MethodSpec.methodBuilder("getActivityMapper")
                .addModifiers(Modifier.PUBLIC)
                .addAnnotation(Override.class)
                .returns(fieldSpec.type)
                .addStatement("return $N",fieldSpec)
        mMessager.printMessage(Diagnostic.Kind.NOTE,"map is ok");
        //获取接口的element
        TypeElement typeElement = mElementUtils.getTypeElement(Config.INTERFACE_MAPPER_NAME);
        //创建类
        TypeSpec typeSpec = TypeSpec.classBuilder(className)
                .addModifiers(Modifier.PUBLIC)
                .addSuperinterface(TypeName.get(typeElement.asType()))
                .addMethod(constructor.build())
                .addMethod(methodSpec)
                .addField(fieldSpec)
                .build();
        mMessager.printMessage(Diagnostic.Kind.NOTE,"JavaFile is end" );
        JavaFile.builder(Config.PACKAGE_NAME,typeSpec).build().writeTo(mFiler);
    }catch (Exception e){
        e.printStackTrace();
    }

}

3、对外开发API调用

1)将我们生成的映射数据都收集起来

fun init(context: Context?) {
    mContext = context
    val classListOfPackage = ClassUtils.getClassListOfPackage(context!!, Config.PACKAGE_NAME)
    ThreadManager.getThreadPool().execute {
        try {
            classListOfPackage.forEach{
                val o = Class.forName(it).newInstance()
                //二次判定,确保加入进去的对象是我们注解生成的
                if (o is IRouterMapper) {
                    val activityMapper = o.getActivityMapper()
                    mRouterList.putAll(activityMapper)
                }
            }
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        } catch (e: InstantiationException) {
            e.printStackTrace()
        } catch (e: ClassNotFoundException) {
            e.printStackTrace()
        }
    }
}

2)开发对外方法调用

fun startActivityNoResult(context: Context, path: String?, bundle: Bundle?) {
    if(TextUtils.isEmpty(path)){
        throw Exception("路径不能未空")
        return
    }
    val className = mRouterList.get(path)
    if(TextUtils.isEmpty(className)){
        throw Exception("该启动Activity未使用@XActivity注解")
        return
    }
    if(context == null){
        throw Exception("context 不能为空")
        return
    }
    var intent = Intent(context, Class.forName(className))
    bundle?.run {
        intent.putExtras(this)
    }
    context.startActivity(intent)
}

详细请查看demo

        目前只是简单的实现了activity的跳转,后续将陆续加入activity传参,返回参数、fragmnet跳转、路由拦截等功能

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android组件是将一个大型的Android应用拆分为多个模块或组件,每个组件都是独立的可重用模块。这种架构有助于代码的模块开发效率的提高和维护的便捷。 在组件架构中,同的组件之间需要进行通信和跳转。路由就是组件之间相互跳转的机制。在路由中,每个组件都可以注册自己路由,其他组件可以通过路由跳转到该组件Android中常用的路由框架有ARouter、RouterX和Fragmentation等。这些框架都提供了路由的基本功能,如路由注册、路由跳转、参数传递等。同时,这些框架还支持拦截器、注解、跨模块通信等高级功能,使得组件之间的通信更加方便和灵活。 总之,组件路由Android开发中的重要概念和技术,它们可以使得应用更加模块、可扩展和易于维护。 ### 回答2: Android组件是一种将一个大型的Android应用拆分成多个独立的组件,每个组件都可以独立开发、测试和维护的开发方式。而路由组件开发中一个重要的技术,用于实现不同组件之间的通信和页面跳转。 在Android组件开发中,不同功能的模块或组件被拆分成独立的子模块,每个子模块可以独立编译、测试和发布。这样的好处是提高开发效率,降低代码耦合度,方便团队协作和模块复用。 而路由作为组件开发中的一个重要技术,用于实现不同组件之间的通信和页面跳转。它能够将各个组件间的依赖关系解耦,简组件间的调用和传递参数。通过路由,一个组件可以通过简单的接口调用来启动其他组件的页面,并可以传递参数,实现页面间的跳转和数据交互。 实现Android组件路由的方法有很多种,比较常见的有利用APT(Annotation Processing Tool)技术动态生成路由表,利用反射技术实现路由跳转,或者利用路由框架实现路由功能。通过使用这些方法,可以简组件间的调用和页面跳转的过程,提高开发效率和代码的可维护性。 总而言之,Android组件是一种将大型应用拆分成独立的组件进行开发的方式,而路由是实现组件之间通信和页面跳转的重要技术。组件开发路由技术的应用可以提高开发效率,降低代码耦合度,并方便团队协作和模块复用。 ### 回答3: Android组件是一种软件开发的架构设计模式,它将一个大型的Android应用程序拆分成若干个独立的组件,每个组件都可以独立开发、测试和部署。这种组件的设计方式旨在提高应用程序的可维护性、可测试性和代码重用性。 在Android组件中,路由是一个非常重要的概念。路由用于管理和控制组件之间的通信和跳转。通过路由,不同的组件可以实现互相之间的跳转和数据传递,从而实现组件之间的解耦和灵活性。 Android组件中的路由通常通过路由表或者路由映射来实现。路由表是一个集中管理和维护路由信息的表格,它记录了组件之间的跳转路径和参数传递规则。当一个组件需要跳转到另一个组件时,它可以通过查询路由表来找到目标组件的路径和参数,从而实现跳转。 另外,路由还可以实现在不同组件之间传递数据。通过路由,可以将数据从一个组件传递给另一个组件,实现数据的共享和交互。这种方式可以避免组件之间直接依赖和耦合,提高代码的可维护性和可扩展性。 总之,Android组件中的路由是实现组件间通信和跳转的重要手段,它可以提高应用程序的可维护性、可测试性和代码重用性。通过良好的路由设计和管理,可以实现更加灵活、模块和可扩展的Android应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值