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

Dagger2:从多个子组件注入活动

如何解决《Dagger2:从多个子组件注入活动》经验,求大佬解答?

本教程展示了如何使用Dagger 2将依赖项注入活动AndroidInjectionModule- 一个非常简单的例子.我的用例有点复杂:

App extends Application implements HasDispatchingActivityInjector,

ActivityOne使用的初始化ActivityModule.使用此活动,DepOne创建依赖项,

ActivityTwo具有在DepTwo没有预先存在的情况下无法正确初始化的依赖项DepOne.

我想出的解决方案是:

创建一个AppComponent作为应用程序的主要组件,

创建一个ComponentTwoas的子组件AppComponent.在运行时添加它,一旦DepOne可用,并DepTwo在其中提供,

注入ActivityTwo内部ComponentTwo.

但是,这需要,ActivityModule目前看起来像这样:

@Module(subcompOnents= {
    ActivityOneSubcomponent.class,
    ActivityTwoSubcomponent.class
})
public abstract class ActivityModule {
    @Binds
    @IntoMap
    @ActivityKey(ActivityOne.class)
    abstract AndroidInjector.Factory bindLoginActivityInjectorFactory(ActivityOneSubcomponent.Builder builder);

    @Binds
    @IntoMap
    @ActivityKey(ActivityTwo.class)
    abstract AndroidInjector.Factory bindWorldActivityInjectorFactory(ActivityTwoSubcomponent.Builder builder);
}

被分成两个不同的模块,一个用于ActivityOne绑定AppComponent,另一个用于ActivityTwo(和其他未来的活动)绑定ComponentTwo.

我做到了,但Dagger在尝试注入时在运行时抗议ActivityTwo:

Caused by: java.lang.IllegalArgumentException: No injector factory bound for Class

似乎应用程序无法看到添加的子组件提供的喷射器工厂.

有什么想法/提示吗?


编辑:我按照要求在下面发布了再现代码(实际上没有Dagger-injectable属性,因为我把它们刮掉了):

ActivityOne.java

public class ActivityOne extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        enterPartTwo();
    }

    private void enterPartTwo() {
        App.app(this).makeComponentTwo();
        ActivityTwo.start(this);
        finish();
    }
}

ActivityOneModule.java

@Module(subcompOnents= {
        ActivityOneSubcomponent.class
})
public abstract class ActivityOneModule {
    @Binds
    @IntoMap
    @ActivityKey(ActivityOne.class)
    abstract AndroidInjector.Factory bindActivityOneInjectorFactory(ActivityOneSubcomponent.Builder builder);
}

ActivityOneSubcomponent.java

@Subcomponent
public interface ActivityOneSubcomponent extends AndroidInjector {
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder {}
}

ActivityTwo.java

public class ActivityTwo extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_world);
    }

    public static void start(Context from) {
        Intent intent = new Intent(from, ActivityTwo.class);
        from.startActivity(intent);
    }
}

ActivityTwoModule.java

@Module(subcompOnents= {
        ActivityTwoSubcomponent.class
})
public abstract class ActivityTwoModule {
    @Binds
    @IntoMap
    @ActivityKey(ActivityTwo.class)
    abstract AndroidInjector.Factory bindActivityTwoInjectorFactory(ActivityTwoSubcomponent.Builder builder);
}

ActivityTwoSubcomponent.java

@Subcomponent
public interface ActivityTwoSubcomponent extends AndroidInjector {
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder {}
}

App.java

public class App extends Application implements HasDispatchingActivityInjector {
    @Inject
    DispatchingAndroidInjector dispatchingAndroidInjector;
    AppComponent appComponent;
    ComponentTwo componentTwo;

    @Override
    public void onCreate() {
        super.onCreate();
        appCompOnent= DaggerAppComponent.create();
        appComponent.inject(this);
    }

    @Override
    public DispatchingAndroidInjector activityInjector() {
        return dispatchingAndroidInjector;
    }

    public void makeComponentTwo() {
        compOnentTwo= appComponent.inGameComponent()
                .build();
    }

    public static App app(Context context) {
        return (App) context.getApplicationContext();
    }
}

AppComponent.java

@Singleton
@Component(modules = {ActivityOneModule.class,
        AndroidInjectionModule.class})
public interface AppComponent {
    void inject(App app);

    ComponentTwo.Builder inGameComponent();
}

ComponentTwo.java

@ScopeTwo
@Subcomponent(modules = {ActivityTwoModule.class})
public interface ComponentTwo {
    @Subcomponent.Builder
    interface Builder {
        ComponentTwo build();
    }
}

ScopeTwo.java

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ScopeTwo {
}

堆栈跟踪:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.abc, PID: 5923
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.abc/com.example.abc.ActivityTwo}: java.lang.IllegalArgumentException: No injector factory bound for Class
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
   at android.app.ActivityThread.-wrap11(ActivityThread.java)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:148)
   at android.app.ActivityThread.main(ActivityThread.java:5417)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalArgumentException: No injector factory bound for Class
   at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:105)
   at dagger.android.AndroidInjection.inject(AndroidInjection.java:61)
   at com.example.abc.ActivityTwo.onCreate(ActivityTwo.java:22)
   at android.app.Activity.performCreate(Activity.java:6237)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
   at android.app.ActivityThread.-wrap11(ActivityThread.java) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:148) 
   at android.app.ActivityThread.main(ActivityThread.java:5417) 
   at java.lang.reflect.Method.invoke(Native Method)

希望它有助于回答这个问题.


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
author-avatar
LeonaL_1巛980
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有