我的匕首2有问题。简单来说,匕首2在片段中进行注入,并且令牌已过期。 TokenAuthenticator要求保存在SharedPreferences中的新令牌。

不会重新创建我的片段,并且Dagger 2使用过期的令牌而不是新的令牌来进行呼叫。

现在,我将详细解释。

匕首2

我的匕首2逻辑微不足道。

NetworkModule.java

@Provides
@Nullable
String provideAuthToken(Context context) {
    return AccountUtils.getCurrentUserToken(context);
}

@Provides
AuthenticationInterceptor provideInterceptor(@Nullable String authToken) {
    return new AuthenticationInterceptor(authToken);
}

@Provides
TokenAuthenticator provideAuthenticator(Context context, @Nullable String authToken) {
    return new TokenAuthenticator(context, authToken);
}

@Provides
OkHttpClient.Builder provideOkHttpClientBuilder(AuthenticationInterceptor interceptor, TokenAuthenticator authenticator) {
    OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    okHttpClientBuilder.connectTimeout(15, TimeUnit.SECONDS);
    okHttpClientBuilder.readTimeout(15, TimeUnit.SECONDS);
    okHttpClientBuilder.writeTimeout(15, TimeUnit.SECONDS);
    if (!okHttpClientBuilder.interceptors().contains(interceptor)) {
        okHttpClientBuilder.addInterceptor(interceptor);
        okHttpClientBuilder.authenticator(authenticator);
    }
    return okHttpClientBuilder;
}


它从SharedPreferences获取令牌,并进行改装以调用API。

改造电话

然后,我对API进行简单调用(这是带有授权令牌的GET)

ProfileFragment.java

@Inject
ViewModelFactory viewModelFactory;
UserViewModel userViewModel;

@Override
public void onAttach(Context context) {
    ((BaseApplication) context.getApplicationContext())
            .getAppComponent()
            .inject(this);
    super.onAttach(context);
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_profile, container, false);
    ...
    userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class);
    userViewModel.getUserInfoMutableLiveData().observe(this, this::consumeResponse);
    ...
}

private void consumeResponse(UserResponse userResponse) {
    switch (userResponse.status) {
        case LOADING:
            showProgressBar();
            break;
        case SUCCESS:
            handleSuccessResponse(userResponse.data);
            break;
        case ERROR:
            dismissAll();
            if (getActivity() != null) {
                ResponseHelper.handleErrorResponse(getActivity(), userResponse.error,
                        mContainer, mMainContainer, this);
            }
            break;
    }
}


刷新令牌

现在让我解释一下会发生什么。

创建了ProfileFragment,匕首2使用注入方式通过获取保存在SharedPreferences中的令牌来创建组件。

ProfileFragment调用该API,由于令牌已过期,因此会获得401错误代码。

调用TokenAuthenticatior刷新令牌,它成功刷新令牌并将NEW令牌保存在SharedPreferences中。

再次调用用户信息,但是,由于未重新创建ProfileFragment,因此将使用具有旧令牌的相同依赖项注入进行调用。它使用旧令牌调用API,然后出现错误401。

如果我现在离开此页面然后再返回,它将正常工作,因为它会再次进行依赖项注入并获取保存在SharedPreferences中的新令牌。

解决方案


这就是为什么我在考虑可以重新注入的某种方法。例如,重新创建配置文件片段,但我认为这不是一个好主意。使用匕首2之前我没有任何问题。


希望有人会帮忙。谢谢!

最佳答案

注入在当前作用域生存期内发生变化的事物通常是一个坏主意,因为您不能再注入某些东西。令牌失效后,您将不得不重新创建整个组件,在这种情况下,您还必须强制重新创建片段。

更好的方法是让您的TokenAuthenticatorAuthenticationInterceptor依赖于AccountUtils,然后他们可以根据需要读取和更新令牌。无需将401传播给用户,因为您可以在身份验证器内以静默方式刷新令牌。

关于android - 刷新 token 时, Dagger 2获得旧 token ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54159012/

10-12 05:18