Android组件化设计5 --- 组件间数据共享

在组件化设计中,除了宿主app能够集成其他组件之外,其他模块之间其实是没有依赖的,相互独立的,例如video和mine之前,video想要调用mine中的图片,只能通过路由完成
Android组件化设计5 --- 组件间数据共享

组件数据共享

1 组件间图片共享

首先,在compiler_api中,定义图片共享的标准Call,与IARouterPath Group同级,在公共基础库中,定义某个模块,例如register模块的标准

interface Call {
}

/**
 * 定义register模块 图片的标准
 */
interface RegisterDrawable : Call {

    fun getDrawable():Int
}

在register模块中,真正实现这个类


@LayRouter(group = "register",path = "register/getDrawable")
class RegisterDrawableImpl : RegisterDrawable {

    override fun getDrawable(): Int {

        return R.drawable.ic_baseline_6k_plus_24
    }
}

1.1 AnnatationProcessor注解处理

这里要注意的是,在RegisterDrawableImpl上使用了LayRouter注解,这个注解在编译的时候,会被扫描到,如果按照之前注解处理器的标准,会报错

Caused by: java.lang.Exception: @LayRouter注解只能在Activity或者Fragment上使用
at com.study.lay_compiler.AnnotationProcessor.process(AnnotationProcessor.kt:107)

这里处理一下,做一个判断,新加了一个Call类型

val callMirror = elementTool!!.getTypeElement(CALL_PACKAGE).asType()
else if(typeTool!!.isSubtype(element.asType(),callMirror)){
    routeBean.setType(RouterType.CALL)
}
public class ARouter_Path_register : IARoutPath {
  public override fun getARoutePath(): Map<String, RouteBean> {
    val pathMap = mutableMapOf<String,RouteBean>()
    pathMap.put("register/getDrawable",RouteBean.create(RegisterDrawableImpl::class,RouterType.CALL,"register/getDrawable","register"))
    pathMap.put("register/RegisterActivity",RouteBean.create(RegisterActivity::class,RouterType.ACTIVITY,"register/RegisterActivity","register"))
    return pathMap
  }
}

最终生成的路由代码中,我们需要的其实就是RouteBean中的RegisterDrawableImpl来传递参数

1.2 RouterManager修改

如果是CALL类型,则直接返回实现类

if(routeBean.getType() == RouterType.ACTIVITY){

    //如果是Activity,那么就执行跳转的逻辑
    val intent = Intent().apply {

        setClass(context,routeBean.getModel().java)
        putExtras(manager.getBundle())
    }

    context.startActivity(intent,manager.getBundle())

}else if(routeBean.getType() == RouterType.CALL){

    //如果是CALL类型,需要执行图片懒加载,返回的就是实现类

    return routeBean.getModel().java.newInstance()
}

1.3 ParamterProcessor修改

else if(typeUtils.isSubtype(typeMirror, callMirror)){

    //activityInstance.drawable = RouterManager.instance.build("").navigation(this) as xxx
    //如果是图片类型,需要动态加载
    func.addStatement(
        "%N.%L = %T.instance.build(%S)!!.navigation(activity) as %T",
        property,
        element.simpleName.toString(),
        ClassName("com.study.complier_api2","RouterManager"),
        name,
        //难点,如何获取属性的类型
        element.asType().asTypeName()
    )
}

通过RouterManager加载目标路由地址的资源文件,然后给调用方赋值

public class MainActivityParams : ParameterGet {
  public override fun getParameter(activity: Any): Unit {
    val activityInstance = activity as MainActivity
    activityInstance.drawable =
        RouterManager.instance.build("register/getDrawable")!!.navigation(activity) as
        RegisterDrawable
  }
}

最终生成的参数代码,其中在MainActivity中调用register模块的资源文件

 @Parameter(name="register/getDrawable")
 lateinit var drawable:RegisterDrawable
 
 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_main)
		
     ParameterManager.instance.loadParams(this)!!.getParameter(this)
     
     val drawable1 = drawable.getDrawable()

     findViewById<ImageView>(R.id.iv_register).setImageResource(drawable1)

在MainActivity中,调用ParameterManager获取参数,就将register模块中的资源通过懒加载的方式赋值给drawable

2 组件间Bean共享

和图片一样,Bean也是一种资源,只需要定义每个模块对于bean的标准,那么就可以在组件之间实现共享

1 公共基础库中,定义某个模块对于bean的标准


/**
 * 定义Register模块对于bean的标准
 */
interface RegisterUser : Call {
    
    //获取具体的bean
    fun getUserInfo():BaseUser
}

2 在具体模块中具体实现这个标准,使用路由实现

@LayRouter(group = "register",path = "register/getUserInfo")
class RegisterUserImpl : RegisterUser {
    
    override fun getUserInfo(): BaseUser {

        val info = RegisterUserInfo()
        info.name = "Mike"
        info.age = 23
        info.token = "sfjal;fnalnfa;fafam;"
        
        return info
    }
}

最终生成的path代码就是这样的

public class ARouter_Path_register : IARoutPath {
  public override fun getARoutePath(): Map<String, RouteBean> {
    val pathMap = mutableMapOf<String,RouteBean>()
    pathMap.put("register/getDrawable",RouteBean.create(RegisterDrawableImpl::class,RouterType.CALL,"register/getDrawable","register"))
    pathMap.put("register/RegisterActivity",RouteBean.create(RegisterActivity::class,RouterType.ACTIVITY,"register/RegisterActivity","register"))
    pathMap.put("register/getUserInfo",RouteBean.create(RegisterUserImpl::class,RouterType.CALL,"register/getUserInfo","register"))
    return pathMap
  }
}

使用方式和图片一致,只要是一个标准即可

 @Parameter(name="register/getDrawable")
 lateinit var drawable:RegisterDrawable

 @Parameter(name = "register/getUserInfo")
 lateinit var bean:RegisterUser


 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_main)

     ParameterManager.instance.loadParams(this)!!.getParameter(this)

     findViewById<TextView>(R.id.tv_hello).text = bean.getUserInfo().name

对于组件之间的数据共享,其实就是通过基础库做每个模块的资源标准定义,然后每个模块做标准的具体实现,通过路由 + Paramter的方式实现数据的懒加载
Android组件化设计5 --- 组件间数据共享

上一篇:解决SQL Server管理器无法连接远程数据库的问题(转)


下一篇:[20180914]oracle 12c 表 full_hash_value如何计算.txt