使用匕首注射活动

时间:2017-12-13 19:47:41

标签: java android dagger-2

我尝试用dvger 2使用mvp&创建示例应用程序。 RXAndroid,每件事都正常但我无法注入Activity以下是我的AppComponent

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

    void inject(MainActivity activity);

    void inject(ResponseService service);

    void inject(MainPresenter presenter);
}

以下是我的模块

@Module
public class AppModule {

    private App app;
    public AppModule(App app) {
        this.app = app;
    }
    private static final String API_ENDPOINT = "url here";

    @Provides
    @Singleton
    public ApiService apiService() {
        OkHttpClient client = new OkHttpClient();


        Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ClassTypeAdapterFactory())
                .registerTypeAdapter(Class.class, new ClassTypeAdapter()).create();


        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API_ENDPOINT)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build();

        return retrofit.create(ApiService.class);
    }

    @Provides
    @Singleton
    ResponseService responseService() {
        return new ResponseService(app.getComponent());
    }

    @Provides
    @Singleton
    MainPresenter mainPresenter() {
        return new MainPresenter(app.getComponent());
    }

    @Provides
    @Singleton
    EventBus eventBus() {
        return EventBus.getDefault();
    }
}

我正确地注入所有东西并且可以使用它们除了ManiActivity时尝试使用它给我空指针以下我如何注入它

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ((App) getApplicationContext())
            .getComponent()
            .inject(this);

    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    initRecyclerView();
    presenter.setView(this);
}

但是当我尝试在我的适配器中将其用作上下文并将其传递给Picasso库时,请给我以下异常java.lang.IllegalArgumentException: Context must not be null. 以下是我如何使用它

@Inject
MainActivity activity;

并在onBindViewHolder中使用它,如下所示

Picasso.with(activity).load(response).fit().into(holder.ivCover);

我的适配器代码

public class ReAdapter extends RecyclerView.Adapter<ReAdapter.RViewHolder> {
    private List<Response> responseList;

    @Inject
    MainActivity appContext;


    public ReAdapter() {
    }

    public void setResponseList(List<Response> responseList) {
        this.responseList = responseList;
        notifyDataSetChanged();
    }

    @Override
    public RViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.response_item, parent, false);
        return new RViewHolder(view);
    }

    @Override
    public void onBindViewHolder(RViewHolder holder, int position) {
        final Response response = responseList.get(position);
            Picasso.with(appContext).load(response.getValue().toLowerCase()).fit().into(holder.ivd);
    }

    @Override
    public int getItemCount() {
        return responseList != null ? responseList.size() : 0;
    }


    public class RViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.ivd)
        ImageView ivd;

        public RViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, itemView);
        }
    }
}

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:4)

  • 您的活动:MainActivity没有@Inject带注释的构造函数(并且不能拥有,因为它是由系统创建的)。
  • AppModule中,没有@Provides带注释的方法返回MainActivity
  • 您正在注入活动中不在适配器中的字段。

结果是Dagger不知道如何创建MainActivity类型的对象。

此特定问题的解决方案是使用Picasso的应用程序上下文,或者甚至更好地使用Picasso创建Dagger对象。

使用以下内容更新您的AppModule

@Provides
@Singleton
Picasso providePicasso(App app) {
    return Picasso.with(app);
}

MainActivity添加字段:

@Inject
ReAdapter adapter;

ReAdapter中修改构造函数并为picasso添加一个字段:

private final Picasso picasso;

@Inject
public ReAdapter(Picasso picasso) {
    this.picasso = picasso;
}

这种方式Dagger可以创建单个Picasso实例。 ReAdapter使用@Inject注释(使用构造函数注入),因此Dagger知道如何创建它。通过在ReAdapter中调用MainActivity时在component.inject(this)中添加MainActivity字段,将初始化适配器字段。