【发布时间】:2019-09-20 16:40:20
【问题描述】:
我有一个非常简单的设置。但是我无法在我正在使用Kodein 的片段中执行任何联网。
片段膨胀并处理所有交互,但网络层依赖项不知何故丢失,因为我每次点击验证此 LoginFragmnet 上的用户名/密码的按钮时都会收到:NotFoundException: No binding found for bind<String>() with ?<Fragment>()。
我不明白这个错误,因为我的 Fragment 类在它的 args/constructor 中没有任何 String?甚至依赖String。
我的应用程序类:
...
override val kodein = Kodein.lazy {
import(androidXModule(this@MyApplication))
bind() from singleton { MyLoginApi(instance(), instance()) }
bind<LoginDataSource>() with singleton { LoginService(instance()) }
bind<LoginRepository>() with singleton { LoginRepositoryImpl(instance()) }
}
...
我的 API
interface MyLoginApi {
@POST("Account/Login")
@FormUrlEncoded
fun login(
@Field("username") username: String,
@Field("password") password: String,
@Field("sessionType") sessionType: String
): Call<BaseApiResponse<Login>>
@GET("Account/Logout")
fun logout(
@Query("token") token: String
): Call<BaseApiResponse<Any>>
companion object {
operator fun invoke(
baseUrl: String,
cache: Cache
): MyLoginApi {
val okHttpClient = OkHttpClient.Builder()
.cache(cache)
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.build()
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl(baseUrl)
.addConverterFactory(JacksonConverterFactory.create())
.build()
.create(MyLoginApi::class.java)
}
}
}
LoginService(数据源)
class LoginService(private val api: MyLoginApi) : LoginDataSource {
private val bus = EventBus.getDefault()
init {
bus.register(this)
}
override fun requestLogin(username: String, password: String) {
val call = api.login(username, password, "mobile")
call.enqueue { result ->
when (result) {
is Result.Success -> {
result.response.body()?.let {
bus.post(LoginResponse(it, username))
} ?: bus.post(LoginResponse(IOException("System Error!")))
}
is Result.Failure -> {
bus.post(LoginResponse(IOException(result.error)))
}
}
}
}
抽象片段类:
abstract class InjectionFragment : Fragment(), KodeinAware {
final override val kodeinContext = kcontext<Fragment>(this)
final override val kodein: Kodein by kodein()
final override val kodeinTrigger: KodeinTrigger?
get() = if (BuildConfig.DEBUG) KodeinTrigger() else super.kodeinTrigger
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
kodeinTrigger?.trigger()
}
}
我知道这个场景非常简单,但我正在尝试将其作为测试,然后再集成到项目的其余部分中。 Fragment 显示,但由于某种原因,一旦我尝试执行数据请求,它就会崩溃并显示错误消息:
org.kodein.di.Kodein$NotFoundException: No binding found for bind<String>() with ?<Fragment>().? { ? }
module androidModule {
bind<String>(tag = "packageResourcePath") with contexted<Context>().provider { String }
bind<String>(tag = "packageCodePath") with contexted<Context>().provider { String }
bind<String>(tag = "packageName") with contexted<Context>().provider { String }
}
更新:
当单步执行我的 Fragment 时,调试器会说 Repository 是 “尚未初始化延迟值。”
【问题讨论】:
-
您在哪里声明/检索您的字符串
packageResourcePath、packageCodePath和packageName?我猜这似乎有什么问题,因为您需要一个字符串来进行网络调用。
标签: android android-fragments kotlin dependency-injection kodein