OpenId App Auth Android:刷新access token传Vue.js及异步返回问题
问题本质
performActionWithFreshTokens是SDK提供的异步方法,内部会发起网络请求完成token校验、过期刷新、本地AuthState更新的全流程,整个执行过程不会阻塞当前线程。
你原代码的执行流存在时间差:同步逻辑走到return state.getAccessToken()语句时,后台的token刷新网络请求尚未返回,回调execute还没被触发,AuthState里存的还是旧的过期token。不要尝试在execute回调里直接向外返回值——这个回调由SDK在后台线程触发,和外层performTokenRefresh方法的调用栈完全分离,根本没有直通外层方法的返回值通道。
落地解决步骤
重构同步返回的逻辑,改成回调式传递刷新结果
放弃原来“方法直接返回String类型token”的同步写法,把方法改成接收自定义回调参数,在execute回调触发时把最新token透传出去,同时做好资源释放和状态持久化:public void performTokenRefresh(TokenRefreshCallback callback) { final AuthState state = AuthUtils.readAuthState(context, key); final AuthorizationService service = new AuthorizationService(context); state.performActionWithFreshTokens(service, new AuthState.AuthStateAction() { @Override public void execute(@Nullable String accessToken, @Nullable String idToken, @Nullable AuthorizationException ex) { // 优先处理刷新异常 if (ex != null) { callback.onRefreshFailed(ex); service.dispose(); return; } // 透传拿到的最新有效token callback.onRefreshSuccess(accessToken); // 重新持久化更新后的AuthState,避免下次启动重复触发登录 AuthUtils.writeAuthState(context, key, state); // 释放AuthorizationService资源,避免内存泄漏 service.dispose(); } }); } // 自定义回调接口 public interface TokenRefreshCallback { void onRefreshSuccess(String freshAccessToken); void onRefreshFailed(AuthorizationException error); }对接Vue前端的WebView通信
等回调真正拿到最新token之后,再通过WebView的JS通信通道把值传给Vue页面,不要在异步流程未完成时提前触发JS调用:// 调用位置示例 performTokenRefresh(new TokenRefreshCallback() { @Override public void onRefreshSuccess(String freshToken) { // WebView的JS调用必须切回主线程执行 runOnUiThread(() -> { webView.evaluateJavascript( `window.__updateAuthToken('${freshToken}')`, null ); }); } @Override public void onRefreshFailed(AuthorizationException error) { // 刷新失败时通知前端跳转重新登录流程 runOnUiThread(() -> { webView.evaluateJavascript( `window.__handleRefreshFailed()`, null ); }); } });避坑提醒
- 不要为了实现同步返回,用
CountDownLatch之类的工具阻塞主线程等待回调,会直接触发ANR,也违反Android主线程禁止网络操作的规范 - 所有涉及WebView JS交互的逻辑,必须切到主线程执行,否则会抛出非法状态异常
- 拿到新token后一定要重新持久化AuthState,否则下次打开App会因为本地状态过期重新走全量授权流程
- 不要为了实现同步返回,用
内容的提问来源于stack exchange,提问作者Jordan Ellison
相关产品推荐
相关产品推荐

