【问题标题】:Android Dagger error cannot find symbol class DaggerDashboardComponentAndroid Dagger 错误找不到符号类 DaggerDashboardComponent
【发布时间】:2017-08-10 15:10:48
【问题描述】:

我正在开发一个使用 Dagger 的现有项目。

这是我第一次尝试使用匕首,对此我有点迷茫。

我尝试从现有片段/模块/组件复制所有现有类、接口和其他所有内容,但出现以下错误:

Error:(7, 42) error: cannot find symbol class DaggerDashboardComponent

我试过Clean Project和Rebuild Project,我试过Invalidate Caches and Restart,我从Android Studio的编译器设置中启用了注释功能,我尝试关闭项目并重新打开它,但由于某种原因(可能是一些错误类生成),我无法编译,因为 dagger 没有生成所需的类。

请在下面找到我创建的所有类/接口:

片段仪表板:

package com.example.app.ui.dashboard;

import com.example.app.R;
import com.example.app.base.AbstractRequestFragment;
import com.example.app.databinding.FragmentDashboardBinding;
import com.example.app.di.component.AppComponent;
import com.example.app.di.component.DaggerDashboardComponent;
import com.example.app.di.module.DashboardModule;
import com.example.app.presenter.dashboard.DashboardPresenter;
import com.example.app.ui.dashboard.DashboardView;

import javax.inject.Inject;

import retrofit2.Call;

/**
 * Created by on 31-05-2017.
 */
public class FragmentDashboard extends AbstractRequestFragment<FragmentDashboardBinding> implements DashboardView {

    @Inject
    DashboardPresenter dashboardPresenter;

    @Override
    protected int layoutToInflate() {
        return R.layout.fragment_dashboard;
    }

    @Override
    protected void injectComponent(AppComponent appComponent) {
        DaggerDashboardComponent.builder()
                .appComponent(appComponent)
                .dashboardModule(new DashboardModule(this))
                .build()
                .inject(this);
    }

    @Override
    protected void initializePresenter(FragmentDashboardBinding fragmentDashboardBinding) {
        dashboardPresenter.initialize(fragmentDashboardBinding);
    }

    @Override
    public void addRequestToStack(Call<?> call) {
        addRequest(call);
    }
}

仪表板组件:

package com.example.app.di.component;

import com.example.app.di.module.DashboardModule;
import com.example.app.di.scope.Fragment;
import com.example.app.presenter.dashboard.DashboardPresenter;
import com.example.app.ui.dashboard.DashboardView;
import com.example.app.ui.dashboard.FragmentDashboard;

import dagger.Component;

/**
 * Created by on 31-05-2017.
 */
@Fragment
@Component(modules = DashboardModule.class, dependencies = AppComponent.class)
public interface DashboardComponent {

    /* BASE */
    void inject(FragmentDashboard fragmentDashboard);

    /* DASHBOARD */
    DashboardView providesDashboardView();
    DashboardPresenter providesDashboardPresenter();

}

仪表板模块:

package com.example.app.di.module;

import com.example.app.di.scope.Fragment;
import com.example.app.ui.dashboard.DashboardView;

import dagger.Module;
import dagger.Provides;

/**
 * Created by on 31-05-2017.
 */
@Module
public class DashboardModule {

    private DashboardView view;

    public DashboardModule(DashboardView view) {
        this.view = view;
    }

    @Fragment
    @Provides
    public DashboardView providesDashboardView() {
        return view;
    }


}

仪表板演示者:

package com.example.app.presenter.dashboard;

import com.example.app.base.BasePresenter;
import com.example.app.databinding.FragmentDashboardBinding;
import com.example.app.databinding.FragmentLoginBinding;

/**
 * Created by on 31-05-2017.
 */
public interface DashboardPresenter extends BasePresenter<FragmentDashboardBinding> {
}

DashboardPresenterImpl:

package com.example.app.presenter.dashboard;

import android.content.Intent;
import android.view.MotionEvent;
import android.view.View;

import com.massivedisaster.activitymanager.ActivityFragmentManager;
import com.example.app.api.ApiListener;
import com.example.app.base.ActivityFullScreen;
import com.example.app.databinding.FragmentDashboardBinding;
import com.example.app.databinding.FragmentLoginBinding;
import com.example.app.presenter.dashboard.DashboardPresenter;
import com.example.app.ui.login.LoginView;
import com.example.app.ui.main.FragmentMain;
import com.example.app.util.ApiManager;
import com.example.app.util.OnOneClickListener;
import com.example.app.util.OnTouchListener;
import com.example.app.util.SnackbarHandler;
import com.example.app.util.ViewHelper;
import com.example.app.util.factory.LoginFactory;

import java.util.ArrayList;

/**
 * Created by on 31-05-2017.
 */
public class DashboardPresenterImpl implements DashboardPresenter {

    private ApiManager apiManager;
    private FragmentDashboardBinding fragmentBinding;
    private LoginFactory loginFactory;
    private LoginView loginView;
    private ViewHelper viewHelper;

    public DashboardPresenterImpl(ApiManager apiManager, LoginFactory loginFactory, LoginView loginView, ViewHelper viewHelper) {
        this.apiManager = apiManager;
        this.loginFactory = loginFactory;
        this.loginView = loginView;
        this.viewHelper = viewHelper;
    }

    @Override
    public void initialize(FragmentDashboardBinding fragmentBinding) {
        this.fragmentBinding = fragmentBinding;

        this.fragmentBinding.btnLogin.setOnClickListener(new OnLoginClickListener());

        // apply on touch cleanup to view and all elements within view
        ArrayList<View> touchables = fragmentBinding.getRoot().getTouchables();
        touchables.add(fragmentBinding.getRoot());
        for (View v : touchables) {
            v.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    return super.onTouch(view, motionEvent);
                }
            });
        }
    }


    // main login listener
    private class OnLoginClickListener extends OnOneClickListener {

        @Override
        public void doOnClick(View view) {
            Intent intent = ActivityFragmentManager.getIntent(loginView.getActivity(), ActivityFullScreen.class, FragmentMain.class);

            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

            loginView.getActivity().startActivity(intent);
        }
    }


}

仪表板视图:

package com.example.app.ui.dashboard;

import com.example.app.base.RequestView;

/**
 * Created by on 31-05-2017.
 */
public interface DashboardView extends RequestView {

}

片段仪表板:

package com.example.app.ui.dashboard;

import com.example.app.R;
import com.example.app.base.AbstractRequestFragment;
import com.example.app.databinding.FragmentDashboardBinding;
import com.example.app.di.component.AppComponent;
import com.example.app.di.component.DaggerDashboardComponent;
import com.example.app.di.module.DashboardModule;
import com.example.app.presenter.dashboard.DashboardPresenter;
import com.example.app.ui.dashboard.DashboardView;

import javax.inject.Inject;

import retrofit2.Call;

/**
 * Created by on 31-05-2017.
 */
public class FragmentDashboard extends AbstractRequestFragment<FragmentDashboardBinding> implements DashboardView {

    @Inject
    DashboardPresenter dashboardPresenter;

    @Override
    protected int layoutToInflate() {
        return R.layout.fragment_dashboard;
    }

    @Override
    protected void injectComponent(AppComponent appComponent) {
        DaggerDashboardComponent.builder()
                .appComponent(appComponent)
                .dashboardModule(new DashboardModule(this))
                .build()
                .inject(this);
    }

    @Override
    protected void initializePresenter(FragmentDashboardBinding fragmentDashboardBinding) {
        dashboardPresenter.initialize(fragmentDashboardBinding);
    }

    @Override
    public void addRequestToStack(Call<?> call) {
        addRequest(call);
    }
}

谁能告诉我这里缺少什么?

【问题讨论】:

    标签: java android android-studio dependency-injection dagger


    【解决方案1】:
    • 你是否在 gradle 中添加了匕首预处理?例如,apt 'com.google.dagger:dagger-compiler:2.x'

    • 您应该检查编译器日志。如果 dagger 发现错误,那么所有 dagger 编译都会失败。 Dagger 对编译器错误的详细说明不是很友好,但是您应该在 dagger 文件中看到一个错误列表,其中一个(通常是第一个)应该会告诉您 dagge 没有生成类的真正原因。

    【讨论】:

      【解决方案2】:

      您尝试注入接口 DashboardPresenter。但是 dagger 不能满足接口依赖,因为它不知道你想要哪个实现。 有两种方法可以解决这个问题:

      使用@Provide 的解决方案 1

      @Provides
      public DashboardPresenter providesDashboardPresenter() 
      {
          return new DashboardPresenterImpl(...);
      }
      

      使用@Binds 的解决方案 2

      @Binds
      abstract DashboardPresenter provideDashboardPresenter(DashboardPresenterImpl impl);
      

      在 DashboardPresenterImpl 的构造函数中添加 @Inject。确保 dagger 可以在模块中构造构造函数的依赖或者通过 @Provide 提供实例。

      public class DashboardPresenterImpl implements DashboardPresenter {
      
          private ApiManager apiManager;
          private FragmentDashboardBinding fragmentBinding;
          private LoginFactory loginFactory;
          private LoginView loginView;
          private ViewHelper viewHelper;
      
          @Inject
          public DashboardPresenterImpl(ApiManager apiManager, LoginFactory loginFactory, LoginView loginView, ViewHelper viewHelper) {
              this.apiManager = apiManager;
              this.loginFactory = loginFactory;
              this.loginView = loginView;
              this.viewHelper = viewHelper;
          }
      }
      

      可能还有更多错误,例如 Ignacio Tomas Crespo 已经说过的。所以请提供更多信息并向我们展示编译器错误。

      【讨论】:

      • 我错过了 providersDashboardPresenter 方法,后来我才意识到。发布此消息后,我才意识到我错过了该方法。无论如何,感谢您的帮助,因为这是正确的答案:)
      猜你喜欢
      • 1970-01-01
      • 2015-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-01
      • 2019-11-01
      • 1970-01-01
      相关资源
      最近更新 更多