Android 选择合适路由

01.选择那个开源路由库

  • 比较有代表性的组件化开源框架有得到得到DDComponentForAndroid、阿里Arouter、聚美Router 等等。
    • 得到DDComponentForAndroid:一套完整有效的android组件化方案,支持组件的组件完全隔离、单独调试、集成调试、组件交互、UI跳转、动态加载卸载等功能。
    • 阿里Arouter:对页面、服务提供路由功能的中间件,简单且够用好用,网上的使用介绍博客也很多,在该组件化案例中,我就是使用这个。
    • Router:一款单品、组件化、插件化全支持的路由框架

02.阿里Arouter基础原理

  • 这里只是说一下基础的思路

    • 在代码里加入的@Route注解,会在编译时期通过apt生成一些存储path和activityClass映射关系的类文件,然后app进程启动的时候会拿到这些类文件,把保存这些映射关系的数据读到内存里(保存在map里),然后在进行路由跳转的时候,通过build()方法传入要到达页面的路由地址。

      • 添加@Route注解然后编译一下,就可以生成这个类,然后看一下这个类。如下所示:
      1
      2
      3
      4
      5
      6
      7
      8
      /**
      * DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
      public class ARouter$$Group$$video implements IRouteGroup {
      @Override
      public void loadInto(Map<String, RouteMeta> atlas) {
      atlas.put("/video/VideoActivity", RouteMeta.build(RouteType.ACTIVITY, VideoActivity.class, "/video/videoactivity", "video", null, -1, -2147483648));
      }
      }
    • ARouter会通过它自己存储的路由表找到路由地址对应的Activity.class(activity.class = map.get(path)),然后new Intent(),当调用ARouter的withString()方法它的内部会调用intent.putExtra(String name, String value),调用navigation()方法,它的内部会调用startActivity(intent)进行跳转,这样便可以实现两个相互没有依赖的module顺利的启动对方的Activity了。

      • 看_ARouter类中的 _navigation方法代码,在345行。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
      final Context currentContext = null == context ? mContext : context;

      switch (postcard.getType()) {
      case ACTIVITY:
      // Build intent
      final Intent intent = new Intent(currentContext, postcard.getDestination());
      intent.putExtras(postcard.getExtras());

      // Set flags.
      int flags = postcard.getFlags();
      if (-1 != flags) {
      intent.setFlags(flags);
      } else if (!(currentContext instanceof Activity)) { // Non activity, need less one flag.
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      }

      // Set Actions
      String action = postcard.getAction();
      if (!TextUtils.isEmpty(action)) {
      intent.setAction(action);
      }

      // Navigation in main looper.
      runInMainThread(new Runnable() {
      @Override
      public void run() {
      startActivity(requestCode, currentContext, intent, postcard, callback);
      }
      });

      break;
      case PROVIDER:
      //这里省略代码
      case BOARDCAST:
      case CONTENT_PROVIDER:
      case FRAGMENT:
      //这里省略代码
      case METHOD:
      case SERVICE:
      default:
      return null;
      }
      return null;
      }

03.使用Arouter注意事项

  • 使用阿里路由抽取工具类,方便后期维护!

    • 首先看一下网络上有一种写法。

      1
      2
      3
      4
      5
      6
      7
      8
      //首先通过注解添加下面代码
      @Route(path = "/test/TestActivity")
      public class TestActivity extends BaseActivity {

      }

      //跳转
      ARouter.getInstance().inject("/test/TestActivity");
    • 优化后的写法

      • 下面这种做法,是方便后期维护。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      //存放所有的路由路径常量
      public class ARouterConstant {
      //跳转到视频页面
      public static final String ACTIVITY_VIDEO_VIDEO = "/video/VideoActivity";
      //省略部分diamagnetic
      }

      //存放所有的路由跳转,工具类
      public class ARouterUtils {
      /**
      * 简单的跳转页面
      * @param string string目标界面对应的路径
      */
      public static void navigation(String string){
      if (string==null){
      return;
      }
      ARouter.getInstance().build(string).navigation();
      }
      }

      //调用
      @Route(path = ARouterConstant.ACTIVITY_VIDEO_VIDEO)
      public class VideoActivity extends BaseActivity {

      }
      ARouterUtils.navigation(ARouterConstant.ACTIVITY_VIDEO_VIDEO);