Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了用Kotlin打造一个Router的示例代码大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

0.

最近接收了从前的项目,之前的@L_262_0@比较凌乱,准备重构。整个项目其实功能比较明显,而且产品还想给他打造成比较成熟牛逼的app,那么组件化开发势在必行。众所周知,模块开发,路由先行,就有了这篇文章。自从用了Kotlin后,感觉Java那些繁琐的语法和喋喋不休的空指针判断让人恶心,于是决定用Kotlin来写一个Router

1.

项目地址Router

@L_262_0@,想好再写,首先分析一下为什么需要模块化开发,为什么路由并且这个路由需要什么功能

1.1

为什么使用模块化开发:随着项目的越来越大,如果把所有功能都放到@L_717_3@module里,对开发和测试来说都有一个效率问题,对开发来讲,由于各种业务@L_262_0@混合在一起,出现问题不好定位,对测试来讲,每次修改都要重新编译整个项目测试。采用组件化开发,讲业务模块分到一个@L_717_3@module里,彼此间相互独立,这样既容易定位问题,也方便测试人员进行测试,因为只需要测试相应的R_788_11845@odule即可。所以我们的项目结构应该是这样的

用Kotlin打造一个Router的示例代码

1.2

为什么使用路由:上面说了,每个module是彼此独立的,而要实现activity的跳转就需要彼此引用,这是我们不想看到的,模块间应该是没有依赖的,那么如何实现不同模块的跳转呢?就需要路由了。

1.3

这个路由需要什么功能:目前所需要的就是根据url实现不同模块之间的Activity跳转包括传递参数,类似startActivity和startActivityForResult,得到不同模块的fragment。

2.

需求想好了,该想怎么实现了。activity跳转有两种,隐式调用显示调用,如果采取隐式调用就要为每个activity注册intent-filter,麻烦,那就只能显示调用了,但是显示调用是需要class对象的,不同module是不能得到class对象的,这怎么搞?编译前得不到,运行时总行吧,所以我们需要一个容器来存储不同moudle里的class对象,并且能通过一个值来进行区分,所以我们需要@L_717_3@map,而值就是用来区分各个activity和fragment的url。

第二个问题来了,url如何确定,class对象怎么得到,又怎么放进map里。这里我们采用注解来做,我们用在注解里声明了url,同时自定义Processor,在编译时生成java文件,里面只有一个方法

public void putRouteClass(Arraymap<String,Class<?>> routableMap) {
routableMap.put("test",MainActivity.class);
}

根据讲每个module里添加注解的Activity和fragment的class对象放入传入的map里。之后再Application的onCreate方法里,调用Router的register方法

fun register(vararg modulenames: String)
  {
    for (modulename in modulenames)
    {
      try
      {
        val cla = Class.forName(Constants.PACKAGE_NAME + Constants.DOT + modulename + "_" + Constants.ROUTER_TABLE_IMp)

        val routerTable = cla.newInstance() as RouterTable

        routerTable.putRouteClass(classmap)
      } catch (e: ClassnotFoundException)
      {
        e.printStackTrace()
      } catch (e: Exception)
      {
        e.printStackTrace()
      }
    }

  }

这个方法很简单,调用每个module里利用Processor生成的对象的putRouteClass方法,将Router里的一个全局map传入,这样,这个map就持有了所有添加注解的Activity和fragment的url以及对应的class对象。有了class对象,那想怎么搞就怎么搞了

//类似startActivity
fun go(context: Context,url: String,extras: Bundle? = null)
  {
    val intent = Intent(context,classmap[url])

    if (extras != null)
    {
      intent.putExtras(extras)
    }

    context.startActivity(intent)
  }

  fun go(fragment: Fragment,extras: Bundle? = null)
  {
    val context=fragment.context
    if(context!=null)
    {
      go(context,url,extras)
    }
  }
  //类似startActivityForResult
  fun goForResult(context: Context,requestCode: Int,classmap[url])

    if (extras != null)
    {
      intent.putExtras(extras)
    }

    if (context is Activity)
    {
      context.startActivityForResult(intent,requestCodE)
    } else if (context is Fragment)
    {
      context.startActivityForResult(intent,requestCodE)
    }
  }

 //得到fragment
  fun getFragment(url: String): Fragment?
  {
    try
    {
      val cla = classmap[url]

      if (cla != null)
      {
        return cla.newInstance() as Fragment
      } else
      {

      }

    } catch (e: ClassnotFoundException)
    {
      e.printStackTrace()
    } catch (e: Exception)
    {
      e.printStackTrace()
    }
    return null
  }

3.有些坑:

3.1

注册注解解释器的时候,不要使用google的autoservice库了,采用resoureces,Meta-INF,不然没效果。别问为什么,我也不知道

3.2

在gradle文件里使用注解解释器使用kapt代替AnnoationProcessor

apply plugin: 'kotlin-kapt'
dependencies {
kapt project(':processor')
api project(':router')
}

3.3

生成的java文件在每个module的build/generated/source/kapt里

4.

其实在上家公司的时候就打算写一个路由,只是由于种种原因最近没能成型,这里只是给大家提供一种思路,作为思路文,就不在普及注解和编译时注解解释器了,请自行查询资料。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

大佬总结

以上是大佬教程为你收集整理的用Kotlin打造一个Router的示例代码全部内容,希望文章能够帮你解决用Kotlin打造一个Router的示例代码所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: