gpt4 book ai didi

java - Dagger 2 未注入(inject)接口(interface)类型

转载 作者:行者123 更新时间:2023-11-30 07:06:49 25 4
gpt4 key购买 nike

我试图在由类实现的接口(interface)类型中注入(inject)字段。

这是我到目前为止所做的事情。

这些是 View 界面:

public interface PostView extends View, ListView<Post>, EmptyView<String> {
}
public interface View {

public void showProgressIndicator();

public void hideProgressIndicator();

public void onSuccess();

public void onFailure();

public void onFailure(String message);
}

public interface ListView<E> {

public void onListItems(List<E> items,
int pageNum,
int pageSize,
boolean next);

}

public interface EmptyView<E> {

public void onEmpty(E e);

public void onEmpty(String message);
}

组件:

@Singleton
@Component(modules = ApiModule.class)
public interface ApiComponent {

Api provideApi();

}

@UserScope
@Component(dependencies = ApiComponent.class, modules = PostModule.class)
public interface PostComponent {

PostPresenter providePostPresenter();

void inject(NetworkTest networkTest);
}

模块:

@Module
public class ApiModule {

private static final Logger logger = Logger.getLogger(ApiModule.class.getSimpleName());

private final String baseUrl;

public ApiModule(String baseUrl) {
this.baseUrl = baseUrl;
}

@Provides
@Singleton
boolean provideIsLoggerEnabled() {
logger.info("proviedIsLoggerEnabled()");
return true;
}

@Provides
@Singleton
OkHttpClient provideOkHttpClient(boolean logEnabled) {
logger.info(" provideOkHttpClient(logEnabled)");
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
Interceptor requestInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
return chain.proceed(chain.request());
}
};
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addInterceptor(requestInterceptor)
.addNetworkInterceptor(interceptor);
return builder.build();
}

@Provides
@Singleton
Api provideApi(OkHttpClient okHttpClient) {
logger.info("provideApi");
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(Api.class);
}

}

@Module
public class PostModule {

private static final Logger logger = Logger.getLogger(PostModule.class.getSimpleName());
private final PostView postView;

public PostModule(PostView postView) {
this.postView = postView;
}

@Provides
@UserScope
PostService providePostService(Api api) {
logger.info("Provider post with api now");
return new PostService(api);
}

@Provides
@UserScope
PostPresenter providePostPresenter(PostService service) {
logger.info("Providing presenter with service now");
return new PostPresenter(postView, service);
}
}

演讲者:

public class PostPresenter extends AbstractPresenter {

private static final Logger logger = Logger.getLogger(PostPresenter.class.getSimpleName());
private PostView postView;
private PostService postService;

public PostPresenter(PostView postView, PostService postService) {
this.postView = postView;
this.postService = postService;
}

@Override
protected View getView() {
logger.info("Getting view");
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public void getPosts() {
logger.info("Getting posts ");
Call<List<Post>> posts = this.postService.getPosts();
postView.showProgressIndicator();
posts.enqueue(new Callback<List<Post>>() {

@Override
public void onResponse(Call<List<Post>> call, Response<List<Post>> rspns) {
postView.onListItems(rspns.body(), 1, 25, true);
postView.hideProgressIndicator();
postView.onSuccess();
}

@Override
public void onFailure(Call<List<Post>> call, Throwable thrwbl) {
onApiCallError(thrwbl);
postView.hideProgressIndicator();
}
});
}
}

public abstract class AbstractPresenter {

private static final Logger logger = Logger.getLogger(AbstractPresenter.class.getSimpleName());

protected abstract View getView();

/*
* General indication whether api call stated or not.
*/
protected void onApiCallStart() {
logger.info("Api call started");
View v = getView();
if (v != null) {
v.showProgressIndicator();
}
}

protected void onApiCallEnd() {
logger.info("Api call finished");
View v = getView();
if (v != null) {
v.hideProgressIndicator();
}
}

/*
* General error handling
*/
protected void onApiCallError(Throwable e) {
logger.info("Api call terminated with error");
View v = getView();
if (v != null && e != null) {
v.onFailure(e.getMessage());
}
}
}

网络测试:

public class NetworkTest implements PostView {

private static final Logger logger = Logger.getLogger(NetworkTest.class.getSimpleName());

private PostComponent component;
@Inject
PostPresenter presenter;

public NetworkTest(ApiComponent apiComponent) {
component = DaggerPostComponent.builder()
.apiComponent(apiComponent)
.postModule(new PostModule(this))
.build();
}

public void init() {
component.inject(this);
}

void showPosts() {
if (presenter != null) {
logger.info("Hurray it worked");
presenter.getPosts();
} else {
logger.warning("Alas it failed");
}
}

@Override
public void showProgressIndicator() {
logger.info("Show progress indicator here");
}

@Override
public void hideProgressIndicator() {
logger.info("Hide progress indicator here");
}

@Override
public void onSuccess() {
logger.info("Api calls successfull");
System.exit(0);
}

@Override
public void onFailure() {
logger.warning("Api call failure");
System.exit(0);
}

@Override
public void onFailure(String message) {
logger.warning(message);
System.exit(0);
}

@Override
public void onListItems(List<Post> items, int pageNum, int pageSize, boolean next) {
logger.info("List received is: " + new Gson().toJson(items));
}

@Override
public void onEmpty(String e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public static void main(String[] args) {
ApiComponent apiComponent = DaggerApiComponent.builder()
.apiModule(new ApiModule("https://jsonplaceholder.typicode.com/"))
.build();

NetworkTest networkTest = new NetworkTest(apiComponent);
networkTest.init();
networkTest.showPosts();
}

}

我的问题是当我尝试使用时

void inject(NetworkTest networkTest); //It works
void inject(PostView postView); //Doesn't work

我希望 PostPresenter 应该被注入(inject)到任何实现 PostView 的类中。

但是当我执行此操作时,@Inject 字段返回 null。有谁对此有任何线索吗?

最佳答案

NetworkTest 有一个 @Inject 字段,Dagger 可以在编译时检测到该字段。 PostView 没有。 Dagger 2 可以在 NetworkTest 和 PostView 上执行注入(inject),但由于 PostView 没有 @Inject 注释的方法,因此 Dagger 2 无法注入(inject)任何内容。

如果你想表达PostView的任意实现者都可以被注入(inject),你应该添加一个@Inject注解的initializeinjectPresenter方法(等);否则,只需从 Dagger 获取/注入(inject)具体类型,以便可以立即注入(inject)它们的所有依赖项。

<小时/>

Dagger 2 user's guide 中所述(强调我的),“Dagger 是一个适用于 Java 和 Android 的完全静态、编译时依赖注入(inject)框架。”与 Guice 或 Spring 不同,Dagger 2 不执行运行时反射,因此(例如)生成的组件方法 inject(PostView) 只能注入(inject)在 PostView 或其父类(super class)型上定义的字段和方法 em>,而不是在子类型上定义的任何内容。

一般来说,我认为您期望(或限制)您的 PostView 接口(interface)实现者要求以某种方式注入(inject) Presenter 是不合理的;如果你想创建一个显式的演示者提供生命周期方法,你可以在 PostView 上做到这一点,而不涉及 Dagger,这样你的类就可以更具体地了解它们的依赖关系,而不是将必要的 deps 与“不必要但包含的”混合在一起根据您的规定。

关于java - Dagger 2 未注入(inject)接口(interface)类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39957632/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com