新装备来了:Butterfly - 全新的Android路由组件化框架,小而强大

Posted River_ly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了新装备来了:Butterfly - 全新的Android路由组件化框架,小而强大相关的知识,希望对你有一定的参考价值。

作者:Season3266

Butterfly - 蝴蝶

Github地址:
https://github.com/ssseasonnn/Butterfly

Butterfly - 小巧而强大的武器,拥有它,让你的android开发如虎添翼,Carry全场!

只有最强大和最经验的勇士才能挥动蝴蝶,但它在战斗中提供了令人难以置信的灵巧

物品介绍: +30 敏捷 +35% 闪避 +25 攻击 +30 攻速

功能介绍

蝴蝶通过两个不同的注解来实现不同的功能:

  • Agile 用于页面导航
  • Evade 用于组件化通信

Agile

  • 导航

通过给Activity添加Agile注解,并设置对应的scheme,随后即可通过Butterfly进行导航,或者导航并获取返回数据

@Agile("test/scheme")
class AgileTestActivity : AppCompatActivity() 
    //...


//导航
Butterfly.agile("test/scheme").carry()

//导航并获取返回数据
Butterfly.agile("test/scheme")
    .carry 
        val result = it.getStringExtra("result")
        binding.tvResult.text = result
    
  • 传递参数

Agile支持附带参数导航,有两种方式,一种是通过拼接scheme,将参数添加到scheme中 另一种是通过调用params方法手动传入参数,或者两者混合进行, 随后可在导航后的页面中获取对应的参数

//拼接scheme
Butterfly.agile("test/scheme?a=1&b=2").carry()

//调用params
Butterfly.agile("test/scheme?a=1&b=2")
    .params("intValue" to 1)
    .params("booleanValue" to true)
    .params("stringValue" to "test value")
    .carry()
  • 解析参数

在导航目的页面,可通过参数的key字段来获取传递的参数值

@Agile("test/scheme")
class AgileTestActivity : AppCompatActivity() 
    val a by lazy  intent?.getStringExtra("a") ?: "" 
    val b by lazy  intent?.getStringExtra("b") ?: "" 
    val intValue by lazy  intent?.getIntExtra("intValue", 0) ?: 0 

除了手动解析参数以外,还可以装备Bracer来实现全自动进行参数解析

@Agile("test/scheme")
class AgileTestActivity : AppCompatActivity() 
    val a by params<String>()
    val b by params<String>()
    val intValue by params<Int>()

Bracer 使用方式详情见: Github 地址:
https://github.com/ssseasonnn/Bracer

  • 拦截器

Agile支持拦截器,可用于在导航前预处理部分逻辑,如进行登录检测 此外拦截器中也可进行导航,但为了避免拦截器套娃,需要添加skipInterceptor()方法以忽略拦截器

//实现自定义拦截器
class TestInterceptor : ButterflyInterceptor 
    override fun shouldIntercept(agileRequest: AgileRequest): Boolean 
        //检测是否需要拦截
        return true
    

    override suspend fun intercept(agileRequest: AgileRequest) 
        //处理拦截逻辑
        println("intercepting")
        delay(5000)
        println("intercept finish")
    


//注册拦截器
ButterflyCore.addInterceptor(TestInterceptor())

//跳过拦截器
Butterfly.agile("test/scheme").skipInterceptor().carry()
  • Action

Agile除了支持页面导航以外,还支持导航Action,Action无页面,可进行某些逻辑处理 首先让自定义的Class继承Action,然后添加@Agile注解并设置scheme,其余和页面导航一致

@Agile("test/action")
class TestAction : Action 
    override fun doAction(context: Context, scheme: String, data: Bundle) 
        //可从data中获取传入的参数
        Toast.makeText(context, "This is an Action", Toast.LENGTH_SHORT).show()
    


//启动Action
Butterfly.agile("test/action").carry()

//Action同样支持传参
Butterfly.agile("test/action?a=1&b=2").carry()

//params 传参
Butterfly.agile("test/action")
    .params("intValue" to 1)
    .carry()
  • 流程控制

Agile除了直接调用carry导航以外,还可以调用flow返回Flow对象, 利用Flow对象可对导航流程进行处理

Butterfly.agile("test/scheme").flow()
    .onStart  println("start") 
    .onCompletion  println("complete") 
    .onEach  println("process result") 
    .launchIn(lifecycleScope)

Evade

蝴蝶使用简单的两个注解即可实现任意组件之间进行通信,而组件之间无需任何直接或间接依赖

例如有两个组件:Module Foo 和Module Bar 需要通信

在Module Foo中,定义接口,并添加Evade注解:

@Evade
interface Home 
    //定义方法
    fun showHome(fragmentManager: FragmentManager, container: Int)

在Module Bar中,定义实现,,并添加EvadeImpl注解:

//实现类名必须以Impl结尾
@EvadeImpl
class HomeImpl 
    val TAG = "home_tag"

    //实现Home接口中的方法, 方法名和方法参数必须相同
    fun showHome(fragmentManager: FragmentManager, container: Int) 
        val homeFragment = HomeFragment()
        fragmentManager.beginTransaction()
            .replace(container, homeFragment, TAG)
            .commit()
    

由于Evade使用类名称作为定义和实现关联的重要依据,因此接口类名和实现类名必须相同,并且实现类名以Impl结尾.

如无法以类名作为关联,也可使用相同的字符串类型作为关联key

@Evade(identity = "same key")
interface Home

@EvadeImpl(identity = "same key")
class OtherNameImpl

随后即可在Module Foo中,使用evade方法获取Home并调用:

val home = Butterfly.evade<Home>()
home.showHome(supportFragmentManager, R.id.container)

除此之外, Evade也支持通过下沉依赖的形式, 进行强关联类型的通信

例如以下三个组件:公共组件Module Base,Module Foo,Module Bar

首先将Home接口下沉至公共组件Module Base中:

@Evade
interface Home 
    fun showHome(fragmentManager: FragmentManager, container: Int)

然后在Module Bar中,实现接口:

//同样需要使用相同的命名规则, 实现类名必须以Impl结尾
@EvadeImpl
class HomeImpl : Home 
    val TAG = "home_tag"

    override fun showHome(fragmentManager: FragmentManager, container: Int) 
        val homeFragment = HomeFragment()
        fragmentManager.beginTransaction()
            .replace(container, homeFragment, TAG)
            .commit()
    

之后便可在Module Foo中,使用evade方法获取Home并调用:

val home = Butterfly.evade<Home>()
home.showHome(supportFragmentManager, R.id.container)

路由表

Butterfly会为每个使用了注解的Module生成一个路由表, 命名规则为: Butterfly[模块名称]Module

手动注册:

class DemoApplication : Application() 
    override fun onCreate() 
        super.onCreate()
        //注册
        ButterflyCore.addModule(ButterflyHomeModule())
        ButterflyCore.addModule(ButterflyFooModule())
        ButterflyCore.addModule(ButterflyBarModule())
    

使用插件自动注册:

1、添加插件依赖

//使用 plugins DSL:
plugins 
  id "io.github.ssseasonnn.butterfly" version "1.0.1"


//或者使用legacy plugin application:
buildscript 
  repositories 
    maven 
      url "https://plugins.gradle.org/m2/"
    
  
  dependencies 
    classpath "io.github.ssseasonnn:plugin:1.0.1"
  


//添加plugin
apply plugin: "io.github.ssseasonnn.butterfly"

2、实现自己的Application类

class DemoApplication : Application() 
    override fun onCreate() 
        super.onCreate()
    

混淆配置

-keep public class zlc.season.butterfly.module.**
-keep public class zlc.season.butterfly.annotation.**
-keep public class zlc.season.butterfly.ButterflyCore *;
-keep public class * extends zlc.season.butterfly.Action

-keep @zlc.season.butterfly.annotation.Agile class * *;
-keep @zlc.season.butterfly.annotation.Evade class * *;
-keep @zlc.season.butterfly.annotation.EvadeImpl class * *;

俗话说得好,蝴蝶在手,天下我有! 这么好的装备你不来一把?

Github地址:
https://github.com/ssseasonnn/Butterfly

最后

前段时间还收集整理了Android高工必备技能知识脑图和核心知识点笔记文档!既能够夯实底层原理核心技术点,又能够掌握普通开发者,难以触及的架构设计方法论。那你在工作中、团队里、面试时,也就拥有了同行难以复制的核心竞争力。

相关的一些知识点解析都已经做了收录整理上传至公号中:Android开发之家,大家可以自行访问查阅。

以上是关于新装备来了:Butterfly - 全新的Android路由组件化框架,小而强大的主要内容,如果未能解决你的问题,请参考以下文章

《绝地求生》测试服数据挖掘 13个全新装备曝光

新服开启 全新《梦想世界》新内容“游园叙梦”今日上线

双Zoom气垫+3层React缓震!史上最强团队鞋来了

全新的Kafka controller来了~~

开启下一个十年,全新 Microsoft 365 订阅版终于来了!

来了!STM32移植LuatOS,潘多拉示例全新教程