didi / DRouter

Android Router Framework
Apache License 2.0
745 stars 93 forks source link

拦截器相关 #41

Closed xujhin-dev closed 1 year ago

xujhin-dev commented 2 years ago

【平台环境】:windows 【Android Studio版本】:chipmunk| 2021.2.1 Patch 1 【编译使用Java版本】:jdk11 【kotlin版本】: 1.6.21 【gradle-plugin版本】:7.1.3 【gradle-wrapper版本】:7.1.3 【drouter版本】:2.3.0 【期望结果】:正常运行app

我的路由参数里面有一个needLogin参数,标志前往此路由需要用户进行登录。我现在想法时声明一个全局的登录拦截器,判断路由中的参数,在拦截器中进行跳转到登录,用户登录成功,继续之前的路由

` @Interceptor( name = "LoginInterceptor",
priority = 1,
global = true )

class LoginInterceptor : IRouterInterceptor { companion object { const val LOGIN_QUERY = "needLogin" const val LOGIN_URl = "https://app.ink.net/login" }

override fun handle(request: Request) {
    if (checkNeedLogin(request)) {
        request.setRedirect(LOGIN_URl)
            .start(request.context, object : RouterCallback.ActivityCallback() {
                override fun onActivityResult(resultCode: Int, data: Intent?) {
                    Log.d("ink", "back")
                }
            })
    } else {
        request.interceptor.onContinue()
    }
}

private fun checkNeedLogin(request: Request): Boolean {
    val needLogin = request.uri.getQueryParameter(LOGIN_QUERY)
    if (needLogin.isNullOrEmpty()) {
        return false
    }
    return needLogin.equals("true", false)
}

}

` 我希望在onActivityResult中获取到用户的登录结果,并根据结果决定是否进行进一步的跳转。但是现在我并不能拿到对应的结果,他甚至并没有执行onActivityResult 方法。

我并不想在拦截器中传值到登录页面,然后再在登录页面中做判断。我想请问一下我是否能直接在拦截器中做处理?

weigao123 commented 2 years ago

可以,这里不适合用重定向,可以考虑下面这种方式

@Interceptor(global = true) public class GlobalInterceptor implements IRouterInterceptor {

public GlobalInterceptor() {
    RouterLogger.getAppLogger().d("GlobalInterceptor create");
}

@Override
public void handle(@NonNull final Request request) {

    switch (request.getUri().toString()) {
        case "/activity/page1":
        case "/activity/page2":
            DRouter.build("/login")
                    .start(request.getContext(), new RouterCallback.ActivityCallback() {
                        @Override
                        public void onActivityResult(int resultCode, @Nullable Intent data) {
                            request.getInterceptor().onContinue();
                        }
                    });
            return;
    }
    request.getInterceptor().onContinue();
}

}

xujhin-dev commented 2 years ago

从activity中跳转是没有问题,但是在fragment 中使用 并不会回调

weigao123 commented 2 years ago

不会回调是什么意思,怎么使用的?

XuJhin commented 2 years ago

我在fragment中使用DRouter.build(uri).start()调用路由跳转。

`@Interceptor( global = true ) class LoginInterceptor : IRouterInterceptor { companion object { const val LOGIN_QUERY = "needLogin" const val LOGIN_URl = "https://app.ink.net/login" }

override fun handle(request: Request) {
    if (checkNeedLogin(request)) {
        DRouter.build(LOGIN_URl)
            .start(request.context, object : RouterCallback.ActivityCallback() {
                override fun onActivityResult(resultCode: Int, @Nullable data: Intent?) {
                    Log.d("result,", "${resultCode}")
                    request.interceptor.onContinue()
                }
            })
        return
    } else {
        request.interceptor.onContinue()
    }
}

private fun checkNeedLogin(request: Request): Boolean {
    val needLogin = request.uri.getQueryParameter(LOGIN_QUERY)
    if (needLogin.isNullOrEmpty()) {
        return false
    }
    return needLogin.equals("true", false)
}

}` 因为拦截器的原因,所以会进入拦截器。最终也正确在拦截器的作用下进入了登录页,但是我在登录页成功登录以后,并不会执行onActivityResult()方法。 从activity中使用DcRouter.start()就能正常执行

weigao123 commented 1 year ago

确认一下context是用的Activity吗?代码的设计即便Activity被回收了也会回调回来的,onActivityResult 里 Log.d("result,", "${resultCode}") 这句执行了吗?

抱歉回复晚了,最近业务有调整,后续可以微信直接联系哈