ARouter的使用以及遇到的问题

2019-03-25  本文已影响0人  成虫_62d0

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

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

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

ARouter支持的特性

ARouter典型应用场景

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) {
          ...
          }
      });
      

遇到的问题

defaultConfig {
    
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ AROUTER_MODULE_NAME : project.getName() ]
            }
        }
}

不同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 {
        //查找到路由地址
        。。。。。
    }
}

上一篇下一篇

猜你喜欢

热点阅读