Skip to content

ARouter 迁移指南

xiaojinzi123 edited this page Dec 6, 2020 · 4 revisions

前言

ARouter 的功能 Component 都有,且更加强大。因此文档更多。但过多的文档不易翻阅,这里根据 ARouter 的每一个功能都做了详细的迁移步骤。由于 ARouter 的局限性,超出 ARouter 的部分不会在这里讲解(比如AndroidX、java8等),具体个性化的需求请看具体相关文档。

一、基础功能

  1. 添加依赖和配置

    //project: build.gradle
    maven { url 'https://jitpack.io' }
    
    //submodule: build.gradle
    dependencies {
      // 这里给出的是默认情况:自动加载所有模块,最低支持 java7 的版本,语言为纯java
      // 特殊需求:java8、AndroidX、kotlin、手动注册模块、手动加载模块,请参考进阶部分
      api 'com.github.xiaojinzi123.Component:component-impl:<version>'
      annotationProcessor "com.github.xiaojinzi123.Component:component-compiler:<version>"
      // kotlin 请使用 kapt
      // kapt "com.github.xiaojinzi123.Component:component-compiler:<version>"
    }
    android {
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = ["HOST": project.getName()]
                }
            }
        }
    }
  2. 初始化SDK optimizeInit(true) 和 autoRegisterModule(true) 用于自动加载,必需同时配合 gradle 插件使用,即下面的第6步(使用 Gradle 插件实现路由表的自动加载)。 如果 optimizeInit(false) 或 autoRegisterModule(false),则为手动注册模块,此时不需要 gradle 插件。此时的具体配置请参考相关文档。

    Config config = Config.with(this)
        .defaultScheme("router")
        .optimizeInit(true)
        .autoRegisterModule(true)
        .build();
    Component.init(BuildConfig.DEBUG, config);
  3. 添加注解

    // 在支持路由的页面上添加注解(必选)
    // 这里的路径需要注意的是至少需要有两级,host/path
    // host 前面必须没有 "/",和 ARouter 不一样
    @RouterAnno(hostAndPath = "test/activity")
    public class YourActivity extend Activity {
        ...
    }
  4. 发起路由操作

    // 1. 应用内简单的跳转(通过URL跳转在'进阶用法'中)
    // 和ARouter的区别:
    //(1) hostAndPath(xx) 而不是 build(xx)
    //(2) forward 而不是 navigation
    //(3) with(Context) 而不是 navigation(Context)
    Router.with().hostAndPath("test/activity").forward();
    
    // 2. 跳转并携带参数
    // 和ARouter的区别:
    //(1) putXXX 而不是 withXXX
    Router.with().hostAndPath("test/activity")
                .putLong("key1", 666L)
                .putString("key3", "888")
                .forward();
  5. 添加混淆规则(如果使用了Proguard)

    # 小金子组件化框架 不要警告
    -dontwarn com.xiaojinzi.component.**
    # 所有本包下面的类和接口都不混淆
    -keep class com.xiaojinzi.component.** {*;}
    -keep interface com.xiaojinzi.component.** {*;}
    #这些是让被标记的类不被混淆
    -keep @com.xiaojinzi.component.anno.InterceptorAnno class * {*;}
    -keep @com.xiaojinzi.component.anno.GlobalInterceptorAnno class * {*;}
    -keep @com.xiaojinzi.component.anno.ConditionalAnno class * {*;}
    -keep @com.xiaojinzi.component.anno.FragmentAnno class * {*;}
    -keep @com.xiaojinzi.component.anno.ServiceAnno class * {*;}
    -keep @com.xiaojinzi.component.anno.support.ComponentGeneratedAnno class * {*;}
    -keep @com.xiaojinzi.component.anno.router.RouterApiAnno interface * {*;}
    #保留生成的 Router Api
    -keep class **.**RouterApiGenerated {*;}
    #几个用户自定义或者自动生成到其他包下的应该不混淆
    -keep class * implements com.xiaojinzi.component.impl.RouterInterceptor{*;}
    -keep class * implements com.xiaojinzi.component.support.IBaseLifecycle{*;}
    -keep class * implements com.xiaojinzi.component.application.IApplicationLifecycle{*;}
    -keep class * implements com.xiaojinzi.component.service.IServiceLifecycle{*;}
    -keep class * implements com.xiaojinzi.component.application.IComponentApplication{*;}
    -keep class * implements com.xiaojinzi.component.support.Inject{*;}
    
  6. 使用 Gradle 插件实现路由表的自动加载 如果你上一步 optimizeInit(true) 传入的是 true, 那么你必须配置此 Gradle 插件

    // 在工程级别的 build.gradle 中添加 classpath
    // 最低支持 java7 的版本
    classpath "com.github.xiaojinzi123.Component:component-plugin:<version>"
    
    // 在壳工程 app 的 builde.gradle 中配置插件
    apply plugin: 'com.xiaojinzi.component.plugin'

二、进阶用法

  1. 特殊需求:java8、AndroidX、kotlin、手动注册模块、手动加载模块 可以查看相关具体配置文档

    1. java8
    2. AndroidX
    3. kotlin
    4. 手动注册模块
    5. 手动加载模块
  2. 解析参数

    // 和ARouter 的 @Autowired 不同,Component 分别为每种场景设计不同的注解
    @RouterAnno(hostAndPath = "test/activity")
    public class Test1Activity extends Activity {
        //必须加参数名字
        @AttrValueAutowiredAnno("age")
        int age;
    
        // 通过name来映射URL中的不同参数
        @AttrValueAutowiredAnno("girl")
        boolean boy;
    
        @ServiceAutowiredAnno
        MyService service;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Components.inject(this);
            // Component 会自动对字段进行赋值,无需主动获取
            Log.d("param", age + boy);
        }
    }
  3. 声明拦截器(拦截跳转过程,面向切面编程)

    1. 单次跳转使用的拦截器

      Router.with(activity).hostAndPath("xxx/xxx")
            // 指定本次跳转的拦截器
            .interceptors()
            .forward();
    2. 全局拦截器(使用特定注解标记一个拦截器即可)

      @GlobalInterceptorAnno(priority = 1000) // 可以指定优先级, 数字越大优先级越高
      public class WebViewInterceptor implements RouterInterceptor {
        //......
      }
    3. 页面拦截器

      // 只需这样子标记, 此界面就拥有了自动完成登录的功能啦. 当然了, 登录的功能是别名为 ”user.login” 的拦截器完成的.
      // 至于登录拦截器
      @RouterAnno(
              path = "user/personCenter",
              interceptorNames = "user.login",
              desc = "用户个人中心界面"
      )
      public class PersonCenterActivity extends AppCompatActivity {
        // .......
      }
  4. 通过依赖注入解耦:服务管理(一) 暴露服务

    // 声明接口,其他组件通过接口来调用服务
    public interface HelloService {
        String sayHello(String name);
    }
    
    // 实现接口
    @ServiceAnno(HelloService.class)
    public class HelloServiceImpl implements HelloService {
        public String sayHello(String name) {
          //...
        }
    }
  5. 通过依赖注入解耦:服务管理(二) 发现服务

    public class Test {
        @ServiceAutowiredAnno
        HelloService helloService;
    
        public Test() {
          Components.inject(this);
    
        }
    
        public void testService() {
          // 1. (推荐)使用依赖注入的方式发现服务,通过注解标注字段,即可使用,无需主动获取
          helloService.sayHello("注入的方式初始化服务(推荐这种方法)");
    
          // 2. 使用依赖查找的方式发现服务,主动去发现服务并使用,下面两种方式分别是byName和byType
          HelloService service = ServiceManager.get(HelloService.class);
          service.sayHello("依赖查找的方式发现服务");
        }
    }
  6. 暴露 Fragment 和发现 Fragment

    //1. 暴露 Fragment
    @FragmentAnno("test/fragment")
    class Fragment : Fragment {...}
    //2. 发现 Fragment
    // 这是一个同步的方法, 即时返回对应的 Fragment
    val fragment = Router.with("test/fragment").navigate()
Clone this wiki locally