java - Retrofit / Dagger - Android:致命异常:API 声明必须是接口
问题描述
我对 Retrofit 和 Dagger 很陌生,我遇到了一个致命的异常:API 声明必须是接口。在以下示例中被抛出:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_network);
findViewById(R.id.test_network_button).setOnClickListener(this);
progressBar = findViewById(R.id.progress_bar);
viewModel = ViewModelProviders.of(this, providerFactory).get(NetworkViewModel.class);
ViewModelProviderFactory.java:
public class ViewModelProviderFactory implements ViewModelProvider.Factory {
private static final String TAG = "ViewModelProviderFactor";
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public ViewModelProviderFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
Provider<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
网络模块.java:
@Module
public class NetworkModule {
@Singleton
@Provides
static StudioDataApi provideNetworkApi(Retrofit retrofit) {
return retrofit.create(StudioDataApi.class);
}
}
完整的 Logcat 错误: https ://pastebin.com/V0hqrEc6
附言
非常感谢任何建议/提示/想法!
解决方案
问题一定是你StudioDataApi
的不是接口。当您调用create
改造时,它会验证您的 api。在这里,您可以看到一个调用,validateServiceInterface
该调用又会在此处抛出上述异常。如果您检查if
上面的语句,它正在检查您正在创建的 api 是否是一个接口。
为什么改造需要这样的东西?
内部改造使用代理模式来创建您的服务。基本上,当您调用create
它时,它会为您的服务/api 返回一个代理。这允许您以您想要的方式处理您的服务,并且当您调用服务方法时,它会确保为您调用 api。
仅此一项不足以引发上述异常,然而,改造并没有重新发明轮子,而是使用 java 的代理模式实现。当调用create
它时,实际上调用Proxy.newProxyInstance
它需要你的服务是一个接口。
推荐阅读
- python - 如何在 Visual Studio Code 中导入 Tkinter/simplegui?
- java - 需要包含外部类的封闭实例。内部类
- php - 带有wordpress页面的div上的响应高度
- c# - 当我们不更新 c# mvc 时如何检索旧的路径图像
- c++ - VS Code Snipets for C/C++ 中花括号的格式
- android - 从服务器下载文件 apk 并安装
- thrift - 将 Thrift 服务请求重定向到在同一台机器上运行的 fork 进程
- r - 同时变异多个具有不同功能的列
- ibm-cloud - 对等 org1 无法加入频道
- css - 无法使用@font-face 显示自定义字体