热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

从AndroidApplication类刷新Dagger2实例

如何解决《从AndroidApplication类刷新Dagger2实例》经验,为你挑选了3个好方法。

我在我的模块类中有一组@Singleton@Provides方法,用于在整个应用程序中创建Singleton实例.一切都很好,除了几个瓶颈情况,如下所示:

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

步骤2.注销后,我正在另一个请求获取auth令牌并SharedPreferences再次插入以供将来使用.

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

需要修复:

    如何触发Dagger提供程序方法强制再次触发或撤消它?

    是否有任何方法可以像应用程序重新启动时那样刷新应用程序类数据.

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

NetworkModule.java(Dagger Module类)

@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组件类)

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


    //ACtivity
    void inject(AuthenticationActivity authenticationActivity);


    void inject(MainActivity mainActivity);


    //Fragments

    void inject(ProjectsListFragment projectsListFragment);



}

Application.java(用于创建Dagger组件的类)

   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> Jeff Bowman ..:

你的问题是@Singleton.@Singleton告诉Dagger您希望Dagger缓存并管理实例状态,并且在执行此操作时,您无法获得大量控制来刷新实例.但是,欢迎您@Singleton@Provides方法中删除并自行管理该实例.如果没有范围,Dagger将为@Provides每个注入请求调用您的方法,这将允许您返回您希望的任何实例并在适当时使其无效.

从昨天看到这个答案,顺便提一下,它也是一个改造服务的NetworkModule,以及在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;
}

没有办法自动刷新共享首选项,但使用上面的按需创建结构,只要当前令牌发生更改,您就可以轻松地将其写入数据持有者.此时,在另一个答案中提取NetworkManager可能是有意义的.



2> azizbekian..:

如何强制触发Dagger提供程序方法以再次触发或吊销它?

是否有任何方法可以像重新启动应用程序一样刷新应用程序类数据?

不,没有这样的触发条件。Component负责为您提供依赖关系。如果您已经完成了一个操作Component并且想要使它无效(即再次创建依赖),则必须从中删除(清空)并创建一个新对象Component。现在,将再次创建所有依赖项。


您能否解释更多,如何配置组件?

3> Chandru..:

根据azizbekian解决方案,我对代码进行了一些修改,它的工作原理很吸引人。非常感谢!

如果使用单击注销按钮,我将清除SharedPreference并通过应用程序中自定义创建的方法将匕首组件分配为null clearComponent(),然后将用户导航到另一个“身份验证”屏幕。请找到下面的完整代码。希望对您有所帮助!

@OnClick(R.id.img_logout)
    void logout() {


        AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());


        alertDialog
                .setMessage("Do you really want to logout?")
                .setCancelable(false)
                .setPositiveButton("Logout", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialogBox, int id) {
                        // ToDo get user input here

                        SharedPrefsUtils.remove(KEY_USERPROFILE, getActivity()); 

                        ((Application) getActivity().getApplication()).clearComponent();


                        ActivityUtils.launchActivity(getActivity(), AuthenticationActivity.class, true);

                    }
                })

                .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialogBox, int id) {
                                dialogBox.cancel();
                            }
                        });

        AlertDialog alertDialogAndroid = alertDialog.create();
        alertDialogAndroid.show();


    }

应用程序

    public class Application extends Application {

                private AppComponent appComponent ;


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

                    Realm.init(this);

                    ButterKnife.setDebug(BuildConfig.DEBUG);


                    appCompOnent= createDaggerComponent();


                }


                  public AppComponent getAppComponent() {

                      return appCompOnent== null ? createDaggerComponent()   : appComponent;
    }


                public void clearComponent() {
                     appCompOnent= null;
                }

          private AppComponent createDaggerComponent() {
             return DaggerAppComponent.builder().appModule(new    AppModule(this)).networkModule(new NetworkModule(this)).build();
    }
            }


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 标题: ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • Android源码中的Builder模式及其作用
    本文主要解释了什么是Builder模式以及其作用,并结合Android源码来分析Builder模式的实现。Builder模式是将产品的设计、表示和构建进行分离,通过引入建造者角色,简化了构建复杂产品的流程,并且使得产品的构建可以灵活适应变化。使用Builder模式可以解决开发者需要关注产品表示和构建步骤的问题,并且当构建流程发生变化时,无需修改代码即可适配新的构建流程。 ... [详细]
  • 基于移动平台的会展导游系统APP设计与实现的技术介绍与需求分析
    本文介绍了基于移动平台的会展导游系统APP的设计与实现过程。首先,对会展经济和移动互联网的概念进行了简要介绍,并阐述了将会展引入移动互联网的意义。接着,对基础技术进行了介绍,包括百度云开发环境、安卓系统和近场通讯技术。然后,进行了用户需求分析和系统需求分析,并提出了系统界面运行流畅和第三方授权等需求。最后,对系统的概要设计进行了详细阐述,包括系统前端设计和交互与原型设计。本文对基于移动平台的会展导游系统APP的设计与实现提供了技术支持和需求分析。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 抽空写了一个ICON图标的转换程序
    抽空写了一个ICON图标的转换程序,支持png\jpe\bmp格式到ico的转换。具体的程序就在下面,如果看的人多,过两天再把思路写一下。 ... [详细]
author-avatar
2414220942_d5ab70
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有