Skip to content
Wiki edited this page Aug 30, 2019 · 17 revisions

GRouter - 为Android组件化开发而生的路由框架

组件化开发架构中,页面跳转组件间调用是至关重要的两大问题,目前Github上已经有多个开源框架,基本都是通过拼接参数来实现页面跳转、获取服务实例。

GRouter 兼容拼接参数方式同时,区别于其他组件化方案推出了安全构造器方案,把工程内的Activity和服务类的构造器生成在GActivityCenter、GComponentCenter、GTaskCenter、GDelegateCenter类中,方便我们安全地调用,避免了拼接参数容易写错,或者目标类被修改带来的运行错误。

Activity 页面跳转

// 不推荐
GRouter.getInstance().startActivity(context, "grouter://activity/user?uid=1")
// 不推荐
GRouter.getInstance().activityBuilder("user").put("uid",1).start(context)
// 推荐
GActivityCenter.UserActivity().uid(123).start(context)

下沉接口式 - 组件间服务调用

// 不推荐
val userService = GRouter.getInstance().getComponent("userService") as UserService
// 推荐
val userService = GComponentCenter.UserServiceImpl()

非下沉式 - 组件间单任务调用

// 不推荐
val user = GRouter.getInstance().getTask("grouter://task/getUser?uid=1").execute().value as User?
// 不推荐
val user = GRouter.getInstance().getTask("getUser").put("uid",1).execute().value as User?
// 推荐
val user = GTaskCenter.GetUserTask().uid(1).execute().value as User?

非下沉式 - 反射代理服务

val accountServiceDelegate = GDelegateCenter.AccountService(context)

特点

  1. 支持AndroidX、支持 Java 和 Kotlin。
  2. 支持FlutterHybrid H5混合项目,可以通过URL调用原生模块获取服务数据、跳转Activity。
  3. 支持多Module项目、多工程项目,多工程项目支持多scheme。
  4. Activity 跳转支持设置默认转场动画,支持设置单次转场动画,支持指定 Flag,支持多级跳转
  5. Activity、Fragment、Task支持参数注入,无需手动解析参数。
  6. 提供RouterComponent、RouterTask、RouterDelegate三种强大的组件间调用服务组件。
  7. 支持生成HTML文档和导入RAP,方便查询。
  8. 支持服务降级,支持通过服务降级Mock数据,可以实现单Module运行调试,提高开发效率。
  9. 各个组件均支持自动生成构造器,避免拼接参数容易写错问题。
  10. 提供 IDEA 插件,支持快捷跳转到目标类,支持 Java 和 Kotlin。
  11. 使用Gradle插件注册Module模块,无需手工填写初始化参数。
  12. RouterComponent支持获取Fragment。
  13. 支持从外部浏览器和其它APP打开内部Activity

该项目会一直致力于组件化解决方案,如果觉得有不足和优化的地方,欢迎提Issues,我们会尽力解决和迭代功能。如果你觉得还不错,可以 star 该 Github 项目,会有持续的功能更新提醒,欢迎你的使用!

  1. 编译期自动添加Proguard混淆规则,免去手动配置的繁琐
  2. 组件化开发实现按需启动,加快调试运行速度,拦截器不能立刻进行初始化,同时需要提供降级功能,如果调用了服务或者跳转页面,需要降级处理。使用Mockito技术,模拟依赖的服务。

使用教程

配置 gradle.properties

# 如果是多Module,请填写填写BaseModule的路径{base-module-name}/src/main/java
GROUTER_SOURCE_PATH =app/src/main/java 
GROUTER_SCHEME =grouterdemo
# 是否开启AndroidX模式
GROUTER_ANDROIDX = false

配置根目录 build.gradle

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.grouter:grouter-gradle-plugin:1.0.0'
    }
}

在每一个Module的 build.gradle 增加

apply plugin: 'grouter'

在 MyApplication 进行初始化

// 需要根据项目使用的json序列化框架实现序列化,下面的fastjson的序列化方案
GRouter.setSerialization(object : GRouter.Serialization {
    override fun serializable(any: Any): String {
        return JSON.toJSONString(any)
    }
    override fun <T> deserializeObject(json: String, clazz: Class<T>): T? {
        return JSON.parseObject(json, clazz)
    }
    override fun <T> deserializeList(json: String, clazz: Class<T>): List<T>? {
        return JSON.parseArray(json, clazz)
    }
})
GRouter.getInstance().init(this, BuildConfig.BUILD_TYPE, null)

@RouterActivity

@RouterActivity("user")
class UserActivity : AppCompatActivity() {
    @RouterField
    var uid: Int? = null
    @RouterField
    var user: User? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        GRouter.inject(this)
        Log.e("uid", uid.toString())
    }
}

支持三种方式跳转,如果是在当前工程建议使用第三种方式跳转

// 方式一
GRouter.getInstance().startActivity(context, "grouterdemo://activity/user?uid=1")
// 方式二
GRouter.getInstance().activityBuilder("user").put("uid",1).start(context)
// 方式三:推荐
GActivityCenter.UserActivity().user(User(1,"Wiki")).start(context)

RouterField参数支持类型:int、long、float、double、boolean、Integer、Long、Double、Float、Boolean、String、int[]、long[]、float[]、double[]、boolean[]、String[]、可序列化List、可序列化Object

详细文档

@RouterTask

@RouterTask(path = "getUser")
public class GetUserTask extends GRouterTask {
    @RouterField
    public int uid;
    @RouterField
    public String name;
    @Override
    public Object process() {
      	// do something
        return new User(uid, "Wiki");
    }
}

支持三种方式调用

// 方式一
val response = GRouter.getInstance().getTask("grouterdemo://task/getUser?uid=1").execute()
// 方式二
val response = GRouter.getInstance().getTask("getUser").put("uid",1).execute()
// 方式三:推荐
var response = GTaskCenter.GetUserTask().uid(1).name("Wiki").execute()
// 支持直接获取返回的对象
val user = response.value as User?
// 支持直接获取返回对象的某个字段
val userName = response.map["name"]
// 支持直接获取返回的json序列化
val text = response.string

方式一,RouterField参数支持类型:int、long、float、double、boolean、Integer、Long、Double、Float、Boolean、String、int[]、long[]、float[]、double[]、boolean[]、String[]、可序列化List、可序列化Object。

如果是方式二和方式三,支持任意类型参数。

详细文档

@RouterComponent

在 BaseModule 增加接口

interface UserService {
    fun getUser(uid: Int): User?
}

在 Module 中编写实现类

@RouterComponent(value = UserService::class, path = "userService")
class UserServiceImpl : UserService {
    constructor() {}
  	@RouterComponentConstructor
    constructor(context: Context) {}
    override fun getUser(uid: Int): User? {
        return null
    }
}

有两种方式调用

val userService = GRouter.getInstance().getComponent("userService") as AccountService
val userService = GComponentCenter.AccountServiceImpl(context)
val user = userService.getUser(1)

详细文档

@RouterDelegate

在Module中创建服务类

@RouterDelegate
class AccountService {
  	constructor() {}
    @RouterDelegateConstructor
    constructor(context: Context) {}
    @RouterDelegateMethod
    fun login(username: String, password: String): User? {
      	// do something
        return null
    }
}

在其它无依赖的Module或者BaseModule都可用直接使用生成的代理类调用

val accountServiceDelegate = GDelegateCenter.AccountService(context)
val user = accountServiceDelegate.login("","")

详细文档

ProGuard 混淆

如果项目用到了混淆,需要添加下面代码到proguard-rules.pro

-keep class com.grouter.GRouterInitializer
-keep @com.grouter.RouterComponent class *
-keep @com.grouter.RouterDelegate class *
-keep @com.grouter.RouterInterceptor class *
-keep @com.grouter.RouterTask class *
-keep @com.grouter.RouterActivity class *
-keepclasseswithmembers class * {
    @com.grouter.RouterField <fields>;
}
-keepclasseswithmembers class * {
    @com.grouter.RouterDelegateMethod <methods>;
}
-keepclasseswithmembers class * {
    @com.grouter.RouterDelegateConstructor <init>(...);
}
-keepclasseswithmembers class * {
    @com.grouter.RouterComponentConstructor <init>(...);
}

License

Copyright 2019 taoweiji

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Clone this wiki locally