从安卓应用类刷新 Dagger 2 实例

我的模块类中有一组 and 方法,用于在整个应用程序中创建单例实例。一切正常,除了一些瓶颈场景,如下所示:@Singleton@Provides

步骤 1.我正在创建一个带有身份验证令牌的改造实例,以便每次都进行经过身份验证的api调用(身份验证令牌的检索和插入通过处理)。但是,问题始于通过清除数据库和共享首选项值注销应用程序后重新启动活动的时间。OKHttpClientSharedPreferences

第2步.注销后,我发出另一个请求来获取身份验证令牌并再次插入以备将来使用。SharedPreferences

步骤3:现在,如果我继续进行其余的api调用,则Dagger和方法的先前实例保持不变,除非并且直到我通过从最近的任务中清除它来重新启动该应用程序。(新的身份验证令牌未更新)@Singleton@Provides

需要修复:

  1. 如何强行触发匕首提供程序方法再次触发或撤销它?

  2. 是否有任何方法可以将应用程序类数据刷新为与应用程序重新启动时类似的行为?

请找到我的项目中使用的Dagger 2架构:

网络模块.java(匕首模块类)

@Module
public class NetworkModule {

  private Context context;


    public NetworkModule(Application app) {
        this.context = app;
    }


    @Provides
    @Named("network.context")
    Context providesContext() {
        return context;
    }

 @Singleton
    @Provides
    OkHttpClient providesOkHttpClient(@Named("network.context")final Context context) {


        final UserProfile userProfile = GsonUtils.createPojo(SharedPrefsUtils.getString(Constants.SHARED_PREFS.USERS_PROFILE, "",context), UserProfile.class);


        Logger.i(userProfile != null && !TextUtils.isEmpty(userProfile.getAuth_token()) ? userProfile.getAuth_token() : "----OAuth token empty---");

        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Interceptor.Chain chain) throws IOException {
                Request original = chain.request();

                Request request = original.newBuilder()
                        .header("Accept", "application/json")
                        .header("Content-Type", "application/json")
                        .header("Api-Version", "application/vnd.addo-v1+json")
                        .header("Access-Token", userProfile != null && !TextUtils.isEmpty(userProfile.getAuth_token()) ? userProfile.getAuth_token() : "")
                        .header("App-Version", Utils.getVersionName(context))
                        .header("Device-Platform","android")
                        .method(original.method(), original.body())
                        .build();

                return chain.proceed(request);
            }

        });

        return httpClient.build();
    }



    @Provides
    @Named(Constants.INJECTION.BASE_URL)
    String providebaseURL() {
        return Constants.URL.BASE_URL;
    }

    @Singleton
    @Provides

    Retrofit providesRetrofit(@Named("network.context")Context context, @Named(Constants.INJECTION.BASE_URL) String baseURL, OkHttpClient okHttpClient) {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseURL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(okHttpClient)
                .build();
        return retrofit;
    }


@Singleton
    @Provides
     NetworkApiService providesNetworkApiService(Retrofit retrofit){
        return retrofit.create(NetworkApiService.class);
    }


 @Singleton
    @Provides
    ProjectPresenter providesProjectPresenter(NetworkApiService networkApiService){
        return new ProjectPresenterImpl(networkApiService);
    }




}

AppComponent.java(Dagger component class)

@Singleton
@Component(modules =  {NetworkModule.class})
public interface AppComponent {


    //ACtivity
    void inject(AuthenticationActivity authenticationActivity);


    void inject(MainActivity mainActivity);


    //Fragments

    void inject(ProjectsListFragment projectsListFragment);



}

应用程序.java(用于创建匕首组件的类)

   public class Application extends Application {

        private AppComponent appComponent ;


        @Override
        public void onCreate() {
            super.onCreate();

            Realm.init(this);

            ButterKnife.setDebug(BuildConfig.DEBUG);


            appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).networkModule(new NetworkModule(this)).build();

        }


        public AppComponent getAppComponent() {
            return appComponent;
        }

    }

请帮助我提供您的建议或提示,以解决Dagger 2的这种奇怪行为。任何类型的解决方案都会对我有很大的帮助,因为我在过去的6天里完全陷入了困境。我无能为力和困惑,因为我的完整架构是建立在此之上的。请原谅我的错别字和更正。如果对此有任何需要澄清,请通知我。提前致谢。


答案 1

如何强行触发匕首提供程序方法再次触发或撤销它?

是否有任何方法可以将应用程序类数据刷新为与应用程序重新启动时类似的行为?

不,没有这样的触发器。 负责为您提供依赖项。如果您已经完成了一个并且想要使其无效(即要再次创建的依赖项),则必须从中释放(null out)并创建一个新的.现在,将再次创建所有依赖项。ComponentComponentComponent


答案 2

您的问题是. 告诉 Dagger 您希望 Dagger 缓存和管理实例状态,并且在执行此操作时,您没有太多控制权来刷新实例。但是,欢迎您退出该方法并自行管理该实例。如果没有作用域,Dagger 将为每个注入请求调用您的方法,这将允许您返回所需的任何实例,并在适当的时候使其无效。@Singleton@Singleton@Singleton@Provides@Provides

请参阅昨天的这个答案,顺便说一句,这也是关于改造服务网络模块以及AppComponent上刷新实例的范围问题。(你们俩不在同一个团队,是吗?

/* Module fields */
OkHttpClient myClient;
String lastToken;

/** Not @Singleton */
@Provides
OkHttpClient providesOkHttpClient(
    @Named("network.context") final Context context, TokenManager tokenManager) {
  String currentToken = getToken();  // gets token from UserProfile

  if (myInstance == null || !lastToken.equals(currentToken)) {
    lastToken = currentToken;
    myInstance = createInstance(currentToken);  // As you have it above

  }
  return myInstance;
}

没有办法自动刷新共享首选项,但是通过上述按需创建结构,您可以在当前令牌更改时轻松地将其写入数据持有者。此时,像在其他答案中一样提取网络管理器可能是有意义的。


推荐