PageAnnotationHandler处理所有形式的URI跳转,根据path匹配由
RouterPage
注解配置的节点。UriAnnotationHandler根据URI的scheme+host,寻找并分发给对应的PathHandler,之后PathHandler再根据path匹配
RouterUri
注解配置的节点。RegexAnnotationHandler根据优先级和正则匹配尝试将URI分发给
RouterRegex
配置的每个节点。StartUriHandler尝试直接使用Android原生的隐式跳转启动URI,用于处理其他类型的URI,例如
tel:*
、mailto:*
。
RouterUri注解可用于Activity或UriHandler的非抽象子类。Activity也会被转化成UriHandler,在Activity中可以通过Intent.getData()
获取到URI。
- path:跳转URI要用的path,必填。path应该以”/“开头,支持配置多个path。
- scheme、host:跳转URI的scheme和host,可选。
- exported:是否允许外部跳转,可选,默认为false。
- interceptors:要添加的Interceptor,可选,支持配置多个。
说明:
WMRouter支持多scheme+host+path的跳转,也支持只有path的跳转。如果RouterUri中配置了scheme、host、path,则跳转时应使用scheme+host+path的完整路径;如果RouterUri中只配置了path,则跳转应直接使用path。
由于多数场景下往往只需要一个固定的scheme+host,不想在每个RouterUri注解上都写一遍scheme、host,这种场景可以在初始化时用
new DefaultRootUriHandler("scheme", "host")
指定默认的scheme、host,RouterUri没有配置的字段会使用这个默认值。
举例
1、用户账户页面只配置path;跳转前要先登录,因此添加了一个LoginInterceptor。
Router.startUri(context, "/account");
2、一个页面配置多个path。
@RouterUri(scheme = "demo_scheme", host = "demo_host", path = {"/path1", "/path2"})
public class TestActivity extends Activity {
}
3、根据后台下发的ABTest策略,同一个链接跳转不同的Activity。其中AbsActivityHandler是WMRouter提供的用于跳转Activity的UriHandler通用基类。
@RouterUri(path = "/home")
public class HomeABTestHandler extends AbsActivityHandler {
@NonNull
protected Intent createIntent(@NonNull UriRequest request) {
if (FakeABTestService.getHomeABStrategy().equals("A")) {
return new Intent(request.getContext(), HomeActivityA.class);
} else {
}
}
}
Router.startUri(context, "/home");
参数如下:
- regex:正则表达式,必填。用于匹配完整的URI字符串。
- priority:优先级,数字越大越先匹配,可选,默认为0。优先级相同时,不保证先后顺序。
- exported:是否允许外部跳转,可选,默认为false。
- interceptors:要添加的Interceptor,可选,支持配置多个。
举例
1、对于指定域名的http(s)链接,使用特定的WebViewActivity打开。
2、对于其他http(s)链接,使用系统浏览器打开。
@RouterRegex(regex = "http(s)?://.*", priority = 1)
public class SystemBrowserHandler extends UriHandler {
@Override
protected boolean shouldHandle(@NonNull UriRequest request) {
return true;
}
@Override
protected void handleInternal(@NonNull UriRequest request, @NonNull UriCallback callback) {
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
request.getContext().startActivity(intent);
callback.onComplete(UriResult.CODE_SUCCESS);
} catch (Exception e) {
}
}
}
实际项目开发过程中,URI跳转常有两种需求:一种是运营后台配置和下发链接让客户端跳转,跳转协议需要和各端保持一致;另一种是App拆分多个工程,需要在工程之间跳转页面,使用路由组件代替显式跳转,实现解耦。
由于种种历史原因,这两套URI可能会出现不兼容的问题,因此需要对两套URI分别做实现。RouterPage注解就是用于实现内部页面跳转而设计的。
RouterPage注解用于指定内部页面跳转,和RouterUri注解相比,RouterPage注解对应的scheme和host为固定的wm_router://page
,不可配置,exported为false也不可配置。
- path:跳转URI要用的path,必填。path应该以”/“开头,支持配置多个path。
- interceptors:要添加的Interceptor,可选,支持配置多个。
举例
// demo://demo/account
@RouterUri(path = "/account", scheme = "demo", host = "demo")
// wm_router://page/account
@RouterPage(path = "/account")
public class AccountActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (PageAnnotationHandler.isPageJump(getIntent())) {
// ...
} else {
// ...
}
}
}
// 对应RouterPage的配置
Router.startUri(context, PageAnnotationHandler.SCHEME_HOST + "/account");
Router.startUri(context, "wm_router://page/account");