使用 dagger 注入活动

Ahm*_*ed 4 java android dagger-2

我尝试使用 mvp 和 RXAndroid 使用 dagger 2 创建示例应用程序,一切正常,但我无法注入 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);
}
Run Code Online (Sandbox Code Playgroud)

以下是我的模块

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我正确地注入了所有东西并且可以使用它们,除非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);
}
Run Code Online (Sandbox Code Playgroud)

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

@Inject
MainActivity activity;
Run Code Online (Sandbox Code Playgroud)

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

Picasso.with(activity).load(response).fit().into(holder.ivCover);
Run Code Online (Sandbox Code Playgroud)

我的适配器代码

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

谁能帮我解决这个问题?

Lor*_*nMK 5

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

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

这个特定问题的解决方案是使用应用程序上下文Picasso,甚至更好地Picasso使用Dagger.

更新你AppModule的:

@Provides
@Singleton
Picasso providePicasso(App app) {
    return Picasso.with(app);
}
Run Code Online (Sandbox Code Playgroud)

MainActivity添加一个字段:

@Inject
ReAdapter adapter;
Run Code Online (Sandbox Code Playgroud)

修改ReAdapter构造函数并添加 picasso 的字段:

private final Picasso picasso;

@Inject
public ReAdapter(Picasso picasso) {
    this.picasso = picasso;
}
Run Code Online (Sandbox Code Playgroud)

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