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

Subcomponent.Builder缺少设置器

如何解决《Subcomponent.Builder缺少设置器》经验,为你挑选了1个好方法。

我需要Android Dagger2.13的帮助。

我正在互联网上关注几个示例,但现在遇到了无法解决的错误。

错误:(23、14)错误:@ Subcomponent.Builder缺少所需模块或子组件的设置器:[com.hugothomaz.fipe.Module.DIMarcaModulo]

我认为最好在GITHub中发布问题类,并在此处包含存储库链接。

https://github.com/hugothomaz/FIPE_Test_Dagger2.11

-FipeApplication-

public class FipeApplication extends Application implements HasActivityInjector, HasFragmentInjector{

    private static final String URL_SEARCH = "http://fipeapi.appspot.com/api/1/";



    @Inject
    DispatchingAndroidInjector dispatchingAndroidInjectorFragment;

    @Inject
    DispatchingAndroidInjector dispatchingAndroidInjectorActivity;


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

    }


    @Override
    public void onTerminate() {
        super.onTerminate();
    }



    private void initializeApplicationComponente() {
        Log.i("app", "FipeApplication initializeApplicationComponente");
        //DaggerDIApplicationComponent.builder().(this).build();

    }



    @Override
    public AndroidInjector fragmentInjector() {
        return dispatchingAndroidInjectorFragment;
    }

    @Override
    public AndroidInjector activityInjector() {
        return dispatchingAndroidInjectorActivity;
    }
}

-DIApplicationModulo-

@Module(subcompOnents= {DIMarcaComponent.class})
public class DIApplicationModulo {

    @Provides
    @Singleton
    GsonConverterFactory provideGsonConverterFactory(){
        GsonConverterFactory factory = GsonConverterFactory.create();
        return factory;
    }

    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(){
        return new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
    }

    @Provides
    @Singleton
    RxJavaCallAdapterFactory provideRxJavaCallAdapterFactory(){
        return RxJavaCallAdapterFactory.create();
    }

    @Provides
    @Singleton
    Retrofit provideRetrofit(OkHttpClient client,
                             GsonConverterFactory converterFactory,
                             RxJavaCallAdapterFactory adapterFactory, String mBaseURL){
        return new Retrofit.Builder()
                .baseUrl(mBaseURL)
                .addConverterFactory(converterFactory)
                .addCallAdapterFactory(adapterFactory)
                .client(client)
                .build();
    }

}

-DIApplicationComponent-

@Singleton
@Component(modules = {
        AndroidInjectionModule.class,
        DIApplicationModulo.class,
        ViewBuilderModule.class
        })
public interface DIApplicationComponent extends AndroidInjector{

    @Component.Builder
    interface Builder{
        @BindsInstance
        DIApplicationComponent.Builder baseURL(String mBaseURL);

        DIApplicationComponent build();
    }

}

-ViewBuilderModule-

@Module(subcompOnents= {DIMarcaComponent.class})
public abstract class ViewBuilderModule {

    @Binds
    @IntoMap
    @FragmentKey(MarcaFragment.class)
    abstract AndroidInjector.Factory bindMarcaFragment(DIMarcaComponent.Builder bulder);
}

-DIMarcaModulo-

@Module
public class DIMarcaModulo {

    private MarcaFragment mView;
    private MarcaAdapterRecyclerImpl mAdapter;
    public Context mContext;


    public DIMarcaModulo(MarcaFragment view, MarcaAdapterRecyclerImpl adapter){
        this.mView = view;
        this.mAdapter = adapter;
        this.mCOntext= view.getActivity().getBaseContext();
        Log.i("app", "DIMarcaModulo instanciado");
        if(adapter==null){
            Log.i("app", "DIMarcaModulo - adapter : nao instanciado");
        }else{
            Log.i("app", "DIMarcaModulo - adapter : instancied");
        }
    }


    @Provides
    @PerFragment
    IMarcaAPI provideMarcaApi(Retrofit retrofit){
        Log.i("app", "DIMarcaModulo provideMarcaApi");
        return retrofit.create(IMarcaAPI.class);
    }


    @Provides
    @PerFragment
    BaseView provideMarcaFragment(){
        Log.i("app", "DIMarcaModulo provideMarcaFragment");
        return mView;
    }


    @Provides
    @PerFragment
    IMarcaAdapterModel provideMarcaAdapterModel(){
        Log.i("app", "DIMarcaModulo provideMarcaAdapterModel");
        return mAdapter;
    }


    @Provides
    @PerFragment
    IMarcaPresenter provideMarcaPresenter(){
        Log.i("app", "DIMarcaModulo provideMarcaPresenter");
        return new MarcaPresenterImpl();
    }


    @Provides
    @PerFragment
    ControllerServiceAPIRest provideControllerServiceAPIRest(){
        Log.i("app", "DIMarcaModulo ControllerServiceAPIRest");
        return new ControllerServiceAPIRest();
    }

    @Provides
    @PerFragment
    Context exposeContext() {
        return mContext;
    }

}

-DIMarcaComponent-

@PerFragment
@Subcomponent(modules = {DIMarcaModulo.class})
public interface DIMarcaComponent extends AndroidInjector {

   @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder{

   }

}

-MarcaFragment-

public class MarcaFragment extends BaseFragment implements IMarcaView, HasFragmentInjector{


    private MarcaAdapterRecyclerImpl mMarcaAdapter;
    private LinearLayoutManager llm;
    private View view = null;


    @Inject
    DispatchingAndroidInjector fragmentDispatchingAndroidInjector;

    @Inject
    public IMarcaPresenter mMarcaPresenter;

    @BindView(R.id.rv_marca)
    protected RecyclerView mRecyclerMarca;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {



        if(view==null){
             view = inflater.inflate(R.layout.fragment_marca, container, false);
         }
         setUnBinder(ButterKnife.bind(this, view));

        return view;
    }

    @Override
    protected void onViewReady(Bundle saveInstanceState, Intent intent) {
        initializeRecyclerMarca();
        super.onViewReady(saveInstanceState, intent);

        if(mMarcaPresenter != null){
            Log.i("app", "MarcaFragment - Presenter nao esta vazio");
        }else{
            Log.i("app", "MarcaFragment - Presenter esta vazio");
        }

        mMarcaPresenter.initSerice();
    }

    private void initializeRecyclerMarca() {
        if(mMarcaAdapter==null){
            mMarcaAdapter = new MarcaAdapterRecyclerImpl();
        }

        mRecyclerMarca.setHasFixedSize(true);
        llm = new LinearLayoutManager(getActivity().getBaseContext());
        llm.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerMarca.setLayoutManager(llm);
        mRecyclerMarca.setAdapter(mMarcaAdapter);
    }


    @Override
    public void onOpenVehicleFragmentByMarcaClicked(Marca marca) {
        // recebendo o item clicado para chamar proxima tela com a Marca clicada.
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        AndroidInjection.inject(this);
    }

    @Override
    public AndroidInjector fragmentInjector() {
        return fragmentDispatchingAndroidInjector;
    }
}

-MarcaPresenterImpl-

public class MarcaPresenterImpl extends BasePresenter implements IMarcaPresenter{

    private static final String TAG_MARCA_PRESENTER = "MarcaPresenterImpl";

    @Inject
    public IMarcaAdapterModel mMarcaAdapterModel;

    @Inject
    public ControllerServiceAPIRest mControllerServiceAPIRest;



    @Inject
    public MarcaPresenterImpl(){

    }

    @Override
    public void onShowMessage(String message) {
        getView().onShowMessage(message);
    }

    @Override
    public void onHideMessage() {
        getView().onHideMessage();
    }

    @Override
    public void onShowProgress(String message) {
        getView().onShowProgress(message);
    }

    @Override
    public void onHideProgress() {
        getView().onHideProgress();
    }

    @Override
    public void onShowToast(String message) {
        getView().onShowToast(message);
    }

    public void refresh() {
        mMarcaAdapterModel.refresh();
    }

    @Override
    public void refreshItem(int id) {

    }

    @Override
    public void listMarcaByServiceForView(List listMarca) {
        mMarcaAdapterModel.setListMarca(listMarca);
    }

    @Override
    public void initSerice() {
        mControllerServiceAPIRest.getMarca();
    }

    @Override
    public void getMarcaClicked(@NonNull Marca marca) {
        getView().onOpenVehicleFragmentByMarcaClicked(marca);
    }


}

-ControllerServiceAPIRest-

public class ControllerServiceAPIRest implements Observer> {

    @Inject
    public IMarcaPresenter mPresenter;

    @Inject
    public IMarcaAPI mMarcaAPI;

    private List listMarca;

    @Inject
    public ControllerServiceAPIRest() {

    }



    protected void getMarca(){
        if(listMarca == null){
            listMarca = new ArrayList<>();
        }
        mPresenter.onShowProgress("Carregando Marca de Veículos...");

        Observable> cakesRespOnseObservable= mMarcaAPI.getAllMarca();
        subscribe(cakesResponseObservable, this);
    }

    private void subscribe(Observable> observable, Observer> observer){

        observable.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }


    @Override
    public void onError(Throwable e) {
        mPresenter.onHideMessage();
        mPresenter.onHideProgress();
        mPresenter.onShowToast("Erro ao carregar Marcas!");
        Log.e("app", "Falha no carregamento de Marcas: " + e.getMessage());
        new Exception(e.getMessage());
    }

    @Override
    public void onComplete() {
        mPresenter.onHideMessage();
        mPresenter.onHideProgress();

        Log.i("app", "ControllerServiceAPIRest - listMarca Position 0: " + listMarca.get(0));
        if (listMarca==null && !listMarca.isEmpty() && listMarca.get(0)!=null){
            mPresenter.listMarcaByServiceForView(listMarca);
            mPresenter.onShowToast("Marcas carregadas!");
        }else{
            mPresenter.onShowToast("Lista não foi carregada!");
        }

    }

    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(List list) {
        listMarca = list;
    }
}

Jeff Bowman .. 5

您需要您的模块:

@PerFragment
@Subcomponent(modules = {DIMarcaModulo.class})
public interface DIMarcaComponent extends AndroidInjector {

而且Dagger无法创建它,因为它没有公共的无参数构造函数:

@Module
public class DIMarcaModulo {
    // ...
    public DIMarcaModulo(MarcaFragment view, MarcaAdapterRecyclerImpl adapter){

但是您直接绑定到Builder中:

@Module(subcompOnents= {DIMarcaComponent.class})
public abstract class ViewBuilderModule {

    @Binds
    @IntoMap
    @FragmentKey(MarcaFragment.class)
    abstract AndroidInjector.Factory
        bindMarcaFragment(DIMarcaComponent.Builder bulder);
}

因此,当dagger.android尝试创建您的对象时:

// AndroidInjector.Builder
abstract class Builder implements AndroidInjector.Factory {
  @Override
  public final AndroidInjector create(T instance) {
    seedInstance(instance);
    return build();
  }

它会注意到您尚未提供DIMarcaModulo实例,并且失败了。您需要遵循SO问题Dagger 2.10 Android子组件和构建器中的建议,这意味着要么给DIMarcaModulo一个可以注入MarcaFragment的公共无参数构造函数,要么重写DIMarcaComponent.Builder#seedInstance:

@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder {

  // This method tells Dagger you need to supply your own DIMarcoModulo.
  public abstract void diMarcoModulo(DIMarcaModulo modulo);

  // dagger.android calls this method automatically, but only this method, so
  // you'll need to call diMarcoModulo from it.
  @Override public void seedInstance(MarcaFragment fragment) {
    diMarcoModulo(fragment, fragment.getMMarcaAdapter());
    bindMarcaFragment(fragment);  // OPTIONAL: See below
  }

  // If you want MarcaFragment to remain injectable, you might need to call into
  // a different @BindsInstance method you define, because you've prevented
  // seedInstance from doing that for you.
  @BindsInstance public abstract void bindMarcaFragment(MarcaFragment fragment);
}

如您所见,MarcaFragment将在DIMarcoModulo安装的图中自动可用,因此,如果您可以避免使用构造函数参数,而将片段作为@Provides方法的参数来接收,则代码可能更易于阅读。您也会遇到我调用的方法的麻烦fragment.getMMarcaAdapter(),因为您进行了注入onAttach并可以访问RecyclerView onCreateView。但是,如果您删除了构造函数参数,并且可以确保在Android有机会创建RecyclerView之前,不要尝试访问RecyclerView,那么这应该不是一个大问题。



1> Jeff Bowman ..:

您需要您的模块:

@PerFragment
@Subcomponent(modules = {DIMarcaModulo.class})
public interface DIMarcaComponent extends AndroidInjector {

而且Dagger无法创建它,因为它没有公共的无参数构造函数:

@Module
public class DIMarcaModulo {
    // ...
    public DIMarcaModulo(MarcaFragment view, MarcaAdapterRecyclerImpl adapter){

但是您直接绑定到Builder中:

@Module(subcompOnents= {DIMarcaComponent.class})
public abstract class ViewBuilderModule {

    @Binds
    @IntoMap
    @FragmentKey(MarcaFragment.class)
    abstract AndroidInjector.Factory
        bindMarcaFragment(DIMarcaComponent.Builder bulder);
}

因此,当dagger.android尝试创建您的对象时:

// AndroidInjector.Builder
abstract class Builder implements AndroidInjector.Factory {
  @Override
  public final AndroidInjector create(T instance) {
    seedInstance(instance);
    return build();
  }

它会注意到您尚未提供DIMarcaModulo实例,并且失败了。您需要遵循SO问题Dagger 2.10 Android子组件和构建器中的建议,这意味着要么给DIMarcaModulo一个可以注入MarcaFragment的公共无参数构造函数,要么重写DIMarcaComponent.Builder#seedInstance:

@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder {

  // This method tells Dagger you need to supply your own DIMarcoModulo.
  public abstract void diMarcoModulo(DIMarcaModulo modulo);

  // dagger.android calls this method automatically, but only this method, so
  // you'll need to call diMarcoModulo from it.
  @Override public void seedInstance(MarcaFragment fragment) {
    diMarcoModulo(fragment, fragment.getMMarcaAdapter());
    bindMarcaFragment(fragment);  // OPTIONAL: See below
  }

  // If you want MarcaFragment to remain injectable, you might need to call into
  // a different @BindsInstance method you define, because you've prevented
  // seedInstance from doing that for you.
  @BindsInstance public abstract void bindMarcaFragment(MarcaFragment fragment);
}

如您所见,MarcaFragment将在DIMarcoModulo安装的图中自动可用,因此,如果您可以避免使用构造函数参数,而将片段作为@Provides方法的参数来接收,则代码可能更易于阅读。您也会遇到我调用的方法的麻烦fragment.getMMarcaAdapter(),因为您进行了注入onAttach并可以访问RecyclerView onCreateView。但是,如果您删除了构造函数参数,并且可以确保在Android有机会创建RecyclerView之前,不要尝试访问RecyclerView,那么这应该不是一个大问题。


推荐阅读
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 【爬虫】关于企业信用信息公示系统加速乐最新反爬虫机制
    ( ̄▽ ̄)~又得半夜修仙了,作为一个爬虫小白,花了3天时间写好的程序,才跑了一个月目标网站就更新了,是有点悲催,还是要只有一天的时间重构。升级后网站的层次结构并没有太多变化,表面上 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文讨论了如何在不使用SearchBar display controller的情况下,单独使用SearchBar并捕获其textChange事件。作者介绍了实际状况,即左侧SliderMenu中的SearchBar需要在主页TableView中显示搜索结果。然后,作者提供了解决方案和步骤,帮助读者实现这一功能。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了如何在使用emacs时去掉ubuntu的alt键默认功能,并提供了相应的操作步骤和注意事项。 ... [详细]
  • php缓存ri,浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
    thinkPHP的F方法只能用于缓存简单数据类型,不支持有效期和缓存对象。S()缓存方法支持有效期,又称动态缓存方法。本文是小编日常整理有关thinkp ... [详细]
  • 本文是一篇翻译文章,介绍了async/await的用法和特点。async关键字被放置在函数前面,意味着该函数总是返回一个promise。文章还提到了可以显式返回一个promise的方法。该特性使得async/await更易于理解和使用。本文还提到了一些可能的错误,并希望读者能够指正。 ... [详细]
  • 本文介绍了在无法联网的情况下,通过下载rpm包离线安装zip和unzip的方法。详细介绍了如何搜索并下载合适的rpm包,以及如何使用rpm命令进行安装。 ... [详细]
  • 近期,某用户在重启RAC一个节点的数据库实例时,发现启动速度非常慢。同时业务部门反馈连接RAC存活节点的业务也受影响。通过对日志的分析, ... [详细]
  • 人脸检测 pyqt+opencv+dlib
    一、实验目标绘制PyQT界面,调用摄像头显示人脸信息。在界面中,用户通过点击不同的按键可以实现多种功能:打开和关闭摄像头, ... [详细]
  • 注:根据Qt小神童的视频教程改编概论:利用最新的Qt5.1.1在windows下开发的一个小的时钟程序,有指针与表盘。1.Qtforwindows开发环境最新的Qt已经集 ... [详细]
  • TerraformVersionTerraformv0.9.11AffectedResource(s)Pleas ... [详细]
  • BugDescriptionWhencategoricalvariablehas ... [详细]
author-avatar
手机用户2502872795
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有