Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

help wanted: 如何自定义BrowserMatcher处理流程 #30

Closed
zhangchaoxu opened this issue Jun 1, 2017 · 10 comments
Closed

help wanted: 如何自定义BrowserMatcher处理流程 #30

zhangchaoxu opened this issue Jun 1, 2017 · 10 comments

Comments

@zhangchaoxu
Copy link

目前发现当path是url路径(startwith http or https)的时候,会先尝试匹配有没有对于的schema,没有的话,则跳转打开系统默认浏览器。

请教如何自定义无法匹配的path的时候,自己处理跳转逻辑,我希望用我app内置的webview来打开这个页面,而不是使用系统内置浏览器。

谢谢

@zhangchaoxu
Copy link
Author

zhangchaoxu commented Jun 1, 2017

我尝试自定义了一个CustomBrowserMatcher,在init之后注册,并且优先级高于BrowserMatcher的0

Router.initialize(this, debug);
        Router.registerMatcher(new CustomBrowserMatcher(1));
public class CustomBrowserMatcher extends AbsMatcher {

    public CustomBrowserMatcher(int priority) {
        super(priority);
    }

    @Override
    public boolean match(Context context, Uri uri, @Nullable String route, RouteRequest routeRequest) {
        return !this.isEmpty(route) && (uri.toString().toLowerCase().startsWith("http://") || uri.toString().toLowerCase().startsWith("https://"));
    }

    @Override
    public Object generate(Context context, Uri uri, @Nullable Class<?> target) {
        if (target != null && Activity.class.isAssignableFrom(target)) {
            Intent intent = new Intent(context, BrowserActivity.class);
            BrowserParam browserParam = new BrowserParam();
            browserParam.setUrl(uri.toString());
            Bundle bundle=new Bundle();
            bundle.putSerializable("browser", browserParam);
            intent.putExtras(bundle);
            return intent;
        } else {
            return null;
        }
    }
}

现在的情况确实先被这个CustomBrowserMatcher捕获,但是产生了两个新疑问:

  1. 居然被一个未在任何地方加入的RouteInterceptor拦截了
  2. generate方法中无法获取到跳转时候传入的参数

@chenenyu
Copy link
Owner

chenenyu commented Jun 1, 2017

  1. 可以继承自BrowserMatcher或者AbsImplicitMatcher, AbsMatcher有两个子类:AbsExplicitMatcher处理显式Intent,AbsImplicitMatcher处理隐式Intent,如果不继承自AbsImplicitMatcher,会被当成显式的情况,会走拦截器的逻辑,这块我会考虑能不能优化。
  2. generate专注与处理目标对象的生成,不操作跳转参数,你可以在match方法内操作RouteRequest,比如routeRequest.setXXX

@chenenyu
Copy link
Owner

chenenyu commented Jun 1, 2017

问题1的出现原因参考这块代码

@zhangchaoxu
Copy link
Author

谢谢
我改为继承自BrowserMatcher以后,问题1解决了。
但是问题2还是有疑问,generate专注于目标对象的生产,目标对象我希望跳转到自定义的BrowserActivity,然后在generate中生成跳转intent,但是在generate中只有uri,没有其他的router.build的时候with的参数,请教一下,我要怎么操作,才可以在我的目标BrowserActivity中获取到with的参数?

@Override
    public Object generate(Context context, Uri uri, @Nullable Class<?> target) {
        //return super.generate(context, uri, target);
        if (target != null && Activity.class.isAssignableFrom(target)) {
            Intent intent = new Intent(context, BrowserActivity.class);
            BrowserParam browserParam = new BrowserParam();
            browserParam.setUrl(uri.toString());
            Bundle bundle = new Bundle();
            bundle.putSerializable("browser", browserParam);
            intent.putExtras(bundle);
            return intent;
        } else {
            return null;
        }
    }

@chenenyu
Copy link
Owner

chenenyu commented Jun 1, 2017

你不需要操作bundle,什么也不需要做,在生成intent之后,会自动把bundle传入intent内,在目标页面直接获取即可。参见这里

@zhangchaoxu
Copy link
Author

收到,多谢指导。

@zhangchaoxu
Copy link
Author

先贴上我自定义的CustomBrowserMatcher

public class CustomBrowserMatcher extends BrowserMatcher {

    public CustomBrowserMatcher(int priority) {
        super(priority);
    }

    @Override
    public boolean match(Context context, Uri uri, @Nullable String route, RouteRequest routeRequest) {
        return super.match(context, uri, route, routeRequest);
    }

    @Override
    public Object generate(Context context, Uri uri, @Nullable Class<?> target) {
        return target != null && Activity.class.isAssignableFrom(target) ? new Intent(context, BrowserActivity.class) : null;
    }
}

我再App中做了注册

init router
        Router.initialize(new Configuration.Builder()
                .setDebuggable(BuildConfig.DEBUG)
                .registerModules("app")
                .build());
        Router.registerMatcher(new CustomBrowserMatcher(1));

以上代码再1.3.x中是正常工作的,最近升级到1.4.0,发现对于http的跳转不起作用了,debug发现在CustomBrowserMatcher.generate中target是null

@zhangchaoxu zhangchaoxu reopened this Mar 19, 2018
@zhangchaoxu
Copy link
Author

1.3.3同样存在问题
1.3.2正常工作

@chenenyu
Copy link
Owner

chenenyu commented Mar 19, 2018

BrowserMatcher继承自AbsImplicitMatcher(即只处理隐式intent),隐式Matcher里的target都为null,代码逻辑在,所以你需要把你的自定义Matcher改为继承AbsExplicitMatcher或者它的子类(显式处理器才能接收到target),注意协调好Matcher的优先级问题。抱歉给你带来的困扰。

@zhangchaoxu
Copy link
Author

非常感谢,贴上正常工作后的代码

public class CustomBrowserMatcher extends AbsExplicitMatcher {

    public CustomBrowserMatcher(int priority) {
        super(priority);
    }

    @Override
    public boolean match(Context context, Uri uri, @Nullable String route, RouteRequest routeRequest) {
        return (uri.toString().toLowerCase().startsWith("http://") || uri.toString().toLowerCase().startsWith("https://"));
    }

    @Override
    public Object generate(Context context, Uri uri, @Nullable Class<?> target) {
        return super.generate(context, uri, BrowserActivity.class);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants