经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Kotlin » 查看文章
kotlin使用属性委托实现依赖注入
来源:cnblogs  作者:轩恺  时间:2021/12/15 9:04:15  对本文有异议

起因

在学习安卓网络通信时翻阅了一下《第三行代码》,决定试着用一下Retrofit,实现了HttpServiceUserService

  1. object HttpService {
  2. private const val BASE_URL = "http://10.0.2.2/"
  3. private val retrofit = Retrofit.Builder()
  4. .baseUrl(BASE_URL)
  5. .addConverterFactory(GsonConverterFactory.create())
  6. .build()
  7. fun <T> create(serviceClass: Class<T>): T = retrofit.create(serviceClass)
  8. inline fun <reified T> create(): T = create(T::class.java)
  9. }
  1. interface UserService {
  2. @GET("user")
  3. fun getUser(
  4. @Query("userId") userId: Long,
  5. ) : Call<User>
  6. }

在使用UserService时就只需要这样调用

  1. HttpService.create<UserService>().getUser().await().let {
  2. //do something
  3. }

虽然已经很简便了,但实际使用的时候需要每次都通过HttpService这个单例类来构造Service,感觉还是有一点麻烦。

灵感

我想到了前段时间看到的一个开源项目ViewBindingKTX,它可以在使用视图绑定时方便很多,这是它样例代码中给出的例子

  1. class MainActivity : AppCompatActivity() {
  2. private val binding: ActivityMainBinding by binding()
  3. override fun onCreate(savedInstanceState: Bundle?) {
  4. super.onCreate(savedInstanceState)
  5. binding.tvHelloWorld.text = "Hello Android!"
  6. }
  7. }

可以看到他使用了by关键词,也就是kotlin的语言特性属性委托。再看看binding()的具体实现

  1. inline fun <reified VB : ViewBinding> ComponentActivity.binding() = lazy {
  2. inflateBinding<VB>(layoutInflater).also {
  3. setContentView(it.root)
  4. if (this is ViewDataBinding) lifecycleOwner = this@binding
  5. }
  6. }

在具体实现时使用了延迟属性来实现在调用时才实例化对象。这样一来在我们使用Activity对应的binding时就会通过得到ActivityMainBinding对象实例,像极了依赖注入。

尝试

仔细一想,我们也可以为Service实现通过属性委托得到实例,来实现依赖注入的功能。先照着binding()来实现一个inject()

  1. inline fun <reified T: BaseHttpService> inject() = lazy {
  2. HttpService.create<T>()
  3. }

再在Activity中使用inject()

  1. class MainActivity : BaseActivity<ActivityMainBinding>() {
  2. private val userService: UserService by inject()
  3. //other code
  4. }

这样一来我们就不需要在Activity中显式地访问HttpService,通过inject()就可以在运行时第一次访问userService时得到对应实例。运行项目,运行成功。

总结

不得不感叹kotlin的强大之处,可以如此轻松地实现依赖注入。并且因为kotlin在实现动态代理时会转为静态代理调用而不是使用反射调用,效率会优于使用java实现。理论上这个用法不止可以在安卓中使用,在其他kotlin项目中也可以轻松实现,在降低耦合的同时简化代码,提高可读性。

原文链接:http://www.cnblogs.com/xuankaicat/p/15657484.html

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号