meituan/WMRouter

如何知道一个页面能否打开呢?(需要在不调用startActivity之前)

Closed this issue · 5 comments

具体如下:
由于提供api给h5方法使用:以前有方法判断能否打开app一个activity,以前方法如下,以前都是在manifest中使用data schema:

boolean canOpen = false;
            if (url != null) {
                url = url.trim();
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                intent.setPackage(context.getPackageName());
                if (null != intent.resolveActivity(context.getPackageManager())) {
                    canOpen = true;
                }
            }


但是使用你们router框架后,似乎没有类似api使用。而类似的
new DefaultUriRequest(context, url)
                  .onComplete(new OnCompleteListener() {
                      @Override
                      public void onSuccess(@NonNull UriRequest request) {
                       
                      }

                      @Override
                      public void onError(@NonNull UriRequest request, int resultCode) {
                       
                      }
                  })
                  .start())

这种必须要真实打开后才知道结果。

****请问有类似的方法可调用吗?

确实没有直接提供这种api,不过有一些办法可以实现效果。之所以没有这个api,因为分发的时候会经过很多UriHandler和UriInterceptor,只要中间有一个UriInterceptor拦截了跳转,或者UriHandler做了处理,都可能影响最终跳转成功的结果,不实际走一遍分发流程没法提前知道结果。对于这个问题有几点看法:

  1. 不是很理解这个需求,H5页面是不是一定要在不打开页面的情况下知道跳转结果?如果不能跳转,H5可以做一些自己的处理,Activity不会打开,这个WMRouter可以处理;如果能跳转,H5也能异步获取结果,既然能跳转,是不是正好也需要打开Activity?

  2. 如果使用的地方都用的RouterUri注解,且没有配置LoginInterceptor之类可能拦截跳转的UriInterceptor,可以通过获取UriAnnotationHandler,读取里面的Map(需要对代码做一些修改),手动根据URI的scheme+host+path判断是否有注册,从而知道能否跳转。

  3. 跳转时覆写startActivityAction,拦截启动Activity的操作,不启动Activity,这样跳转时会走完整的分发流程,而最终并没有真的启动Activity,相当于实现了不打开页面的情况下知道跳转结果的效果。

这个需求对我们是合理的:h5方面如果不能打开,h5会降级用h5去打开一个http://...的页面或者别的提示什么的。能打开,下一步h5才执行真正打开的动作。这套设计和ios一起共用的。总之对我们而言,需要这个功能。
app确实到了后面,必须要有一个router框架,能统一处理一些共用逻辑,以前也看过很多别的框架,目前来看,你们这套更适合我们,替换以前的代码更方便,但是仅仅在上面一个问题上有些困扰。

你说的2对一些native是可行的,但是像tel:10086, smsto:等还要多判断下了。目前似乎你说的方法3更适合解决该问题。

好的,可以试试方案3,要注意一下如果后续有自定义UriHandler的情况,打开Activity也应该统一用DefaultActivityLauncher.startActivity中的逻辑,先尝试用StartActivityAction启动,而不是直接自己启动Activity,要不然方案3就失效了。

好的,多谢

已经用方案2解决我的问题,这里帖下方便有需要的人:

   public static boolean canOpenUrl(Context context, String url) {
        if (url != null) {
            return  Single.create((SingleOnSubscribe<Boolean>) emitter -> new DefaultUriRequest(context, url)
                    .overrideStartActivity(new StartActivityAction() {
                        @Override
                        public boolean startActivity(@NonNull UriRequest request, @NonNull Intent intent) throws ActivityNotFoundException, SecurityException {
                            if (null != intent.resolveActivity(context.getPackageManager())) {
                                return true;
                            } else {
                                return false;
                            }
                        }
                    })
                    .onComplete(new OnCompleteListener() {
                        @Override
                        public void onSuccess(@NonNull UriRequest request) {
                            emitter.onSuccess(true);
                        }

                        @Override
                        public void onError(@NonNull UriRequest request, int resultCode) {
                            emitter.onSuccess(false);
                        }
                    })
                    .start()).blockingGet();

        }
        return false;
    }