ARouter的使用以及遇到的问题

app随着业务的越来越复杂,代码量越来越大,导致了各种问题亟待解决:

  • 整体打包速度变慢。
  • 业务间耦合较高。

为了解决上述问题,我们进行了组件化重构,本文不对组件化方案进行详细的介绍。组件化重构又要解决组件与组件之间的耦合问题—例如页面之间的跳转。所以在项目中引入了 ARouter

本文将介绍ARouter的使用以及使用中遇到的问题。

ARouter支持的特性

  • 支持url标准解析以及跳转(url绑定特定的activity页面),自动注入参数。

  • 多组件支持(解耦)

  • 支持跳转拦截处理—登录,统计以及其他逻辑

  • 跨组件通信解耦以及依赖倒置

ARouter典型应用场景

  • 不同组件之间activity的跳转
  • h5页面跳转到activity
  • 登录拦截处理—很多跳转要先判断是否登录,如果没有登录跳转到登录页面

ARouter的使用姿势

  1. 配置

    • buid.gradle文件添加依赖和配置

      android {
          defaultConfig {
              ...
              javaCompileOptions {
                  annotationProcessorOptions {
                      arguments = [AROUTER_MODULE_NAME: project.getName()]
                  }
              }
          }
      }
      
      dependencies {
          // Replace with the latest version
          compile 'com.alibaba:arouter-api:?'
          annotationProcessor 'com.alibaba:arouter-compiler:?'
          ...
      }
      
    • 在代码中添加注解

      @Route(path = "/test/activity")
      public class YourActivity extend Activity {
          ...
      }
      
    • 在application中初始化

      if (isDebug()) {           // These two lines must be written before init, otherwise these configurations will be invalid in the init process
          ARouter.openLog();     // Print log
          ARouter.openDebug();   // Turn on debugging mode (If you are running in InstantRun mode, you must turn on debug mode! Online version needs to be closed, otherwise there is a security risk)
      }
      ARouter.init(mApplication); // As early as possible, it is recommended to initialize in the Application
      

      这里注意注释,在debug模式下必须要在初始化之前调用ARouter.openLog() ARouter.openDebug

    • 代码调用

      // 1. Simple jump within application (Jump via URL in 'Advanced usage')
      ARouter.getInstance().build("/test/activity").navigation();
      
      // 2. Jump with parameters
      ARouter.getInstance().build("/test/1")
                  .withLong("key1", 666L)
                  .withString("key3", "888")
                  .withObject("key4", new Test("Jack", "Rose"))
                  .navigation();
      
    • proguard文件的配置

      -keep public class com.alibaba.android.arouter.routes.**{*;}
      -keep public class com.alibaba.android.arouter.facade.**{*;}
      -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}
      
      # If you use the byType method to obtain Service, add the following rules to protect the interface:
      -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider
      
      # If single-type injection is used, that is, no interface is defined to implement IProvider, the following rules need to be added to protect the implementation
      # -keep class * implements com.alibaba.android.arouter.facade.template.IProvider
      
  2. 使用场景

    • 根据url跳转

      public class SchameFilterActivity extends Activity {
       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
        
           Uri uri = getIntent().getData();
           ARouter.getInstance().build(uri).navigation();
           finish();
       }
        }
      
      <activity android:name=".activity.SchameFilterActivity">
          <!-- Schame -->
          <intent-filter>
              <data
                  android:host="m.aliyun.com"
                  android:scheme="arouter"/>
      
              <action android:name="android.intent.action.VIEW"/>
      
              <category android:name="android.intent.category.DEFAULT"/>
              <category android:name="android.intent.category.BROWSABLE"/>
          </intent-filter>
      </activity>
      
    • 解析参数

      @Route(path = "/test/activity")
      public class Test1Activity extends Activity {
          @Autowired
           public String name;
          @Autowired
          int age;
          @Autowired(name = "girl") // Map different parameters in the URL by name
          boolean boy;
          @Autowired
          TestObj obj; 
          
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              ARouter.getInstance().inject(this);
      
              // ARouter will automatically set value of fields
              Log.d("param", name + age + boy);
          }
      

      ARouter.getInstance().inject(this);这行代码一定要在oncreate中调用。还支持自定义的参数解析,有这方面需求的可以去ARouter的github页面

    • 面向切面的拦截器

      // A more classic application is to handle login events during a jump so that there is no need to repeat the login check on the target page.
      // Interceptors will be executed between jumps, multiple interceptors will be executed in order of priority
      @Interceptor(priority = 8, name = "test interceptor")
      public class TestInterceptor implements IInterceptor {
          @Override
          public void process(Postcard postcard, InterceptorCallback callback) {
              ...
              // No problem! hand over control to the framework
              callback.onContinue(postcard);  
              
              // Interrupt routing process
              // callback.onInterrupt(new RuntimeException("Something exception"));      
      
              // The above two types need to call at least one of them, otherwise it will not continue routing
          }
      
          @Override
          public void init(Context context) {
              // Interceptor initialization, this method will be called when sdk is initialized, it will only be called once
          }
      }
      
    • 跳转回调

      // U can get the result of a single jump
      ARouter.getInstance().build("/test/1").navigation(this, new NavigationCallback() {
          @Override
          public void onFound(Postcard postcard) {
          ...
          }
      
          @Override
          public void onLost(Postcard postcard) {
          ...
          }
      });
      

遇到的问题

  • ARouter.getInstance().inject(this);
    我们有一个singletask启动模式的activity,在onNewIntent方法中调用ARouter.getInstance().inject(this);得不到参数,查看ARouter在build过程中生成的代码可以知道它是调用了activity的getIntent来获取参数的,但是onNewIntent中的intent和在onCreate方法中的intent并不相同,所以需要在onNewIntent方法中调用setIntent方法,然后就能得到参数了。

    ARouter::Compiler >>> No module name, for more information, look at gradle log.
    检查项目依赖的全部module包括module依赖的module(没有页面的module也算),在每个module的 build.gradle中加上下面的代码。

defaultConfig {
    
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ AROUTER_MODULE_NAME : project.getName() ]
            }
        }
}
  • ARouter there's no route matched

不同module的一级路径必须不同,否则会导致一个moudle中的一级路径失效

下面是抛出异常的源代码

    public synchronized static void completion(Postcard postcard) {
    if (null == postcard) {
        throw new NoRouteFoundException(TAG + "No postcard!");
    }

    //查找RouteMeta对象,如果存在说明路由成功,如果失败说明还没有被加载或者这个path就是错误的
    RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
    if (null == routeMeta) {
      // 通过groupsIndex去找IRouteGroup的实现类
        Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());
        if (null == groupMeta) {
            throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");
        } else {
            // 通过反射获取IRouteGroup的实现类,然后加载到内存
            IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
            iGroupInstance.loadInto(Warehouse.routes);
            // 加载到内存后Warehouse.groupsIndex去掉这个group
            Warehouse.groupsIndex.remove(postcard.getGroup());
        }
    } else {
        //查找到路由地址
        。。。。。
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容