Johnny Shieh

人如果没有梦想,跟咸鱼有什么分别


  • 首页

  • 分类

  • 归档

  • 标签

  • 读书

  • 小伙伴

  • 关于

  • 搜索

Kotlin 中延迟初始化的非空属性,如何避免使用不必要的 !! 操作符

发表于 2017-06-22 | 分类于 Kotlin | | 阅读次数

最近在写 Kotlin 版本的 Gank 客户端(干货集中营 app)时,发现一个非常烦人的事情:有的成员属性不能在构造函数中初始化,会在稍后某的地方完成初始化,可以确定是非空,但是因为不能在构造时初始化只能定义为可能为空的类型(T?),然后在后面调用时都要加上!!操作符。下面本文将逐步分析这种场景的解决方案,最终提供一种优雅的方式。

这里先给出最终解决方式(为了部分喜欢直奔主题的开发者):

  • notNull 委托属性

  • lateinit 修饰符

注:本文的第一种解决方法来源于《Kotlin For Android Developers》,学习 Kotlin 的朋友有兴趣可以看看。

问题场景

相信肯定有很多开发者也遇到一样的场景,因为这种情况在 Android 中很常见:在 Activity、Fragment、Service… 中经常有些属性只能在onCreate中才能完成初始化,而且之后不会再修改可以确定为非空,如下面代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class App : Application() {
companion object {
var instance: App? = null // kotlin 中的单例
}
var okHttpClient: OkHttpClient? = null // 使用 Dagger 2 注入
@Inject set
override fun onCreate() {
super.onCreate()
instance = this
// 使用 Dagger 2 注入 okHttpClient 实例,完成初始化
...
}
}

上面代码中instance和okHttpClient都只能在onCreate函数中完成初始化,但是之后都是可以确定是非空,但是在后面调用只能通过instance!!和okHttpClient!!的方式调用,感觉非常变扭。

阅读全文 »

Dagger 2 完全解析(五),Kotlin 中使用 Dagger 2

发表于 2017-06-19 | 分类于 Android | | 阅读次数

Dagger 2 完全解析系列:

Dagger 2 完全解析(一),Dagger 2 的基本使用与原理

Dagger 2 完全解析(二),进阶使用 Lazy、Qualifier、Scope 等

Dagger 2 完全解析(三),Component 的组织关系与 SubComponent

Dagger 2 完全解析(四),Android 中使用 Dagger 2

Dagger 2 完全解析(五),Kotlin 中使用 Dagger 2

Dagger 2 完全解析(六),dagger.android 扩展库的使用

本系列文章是基于 Google Dagger 2.11-rc2 版本

Google I/O 2017 大会上宣布 Kotlin 成为 Android 开发一级语言,kotlin 语言作为 Google 的亲儿子,前途一片光明,而且 Kotlin 加入了很多现代语言特性。最近把我之前写的一个开源项目重构为 Kotlin 版本 – Kotlin 版本的 Gank app,以此来学习 kotlin 语言。其中在 Kotlin 语言中使用 Dagger 2 的写法与 Java 中有些变化,所以写下这篇文章记录下如何在 Kotlin 语言中使用 Dagger 2。

本文中的 Kotlin 版本为 1.2.10

Dagger 2 依赖

引入方式与之前有所区别,Dagger 2 根据注解在编译时生成静态代码,所以需要注解处理器,而 Kotlin 中注解处理工具为 Kotlin Annotatino processing tool(kapt)。

阅读全文 »

Dagger 2 完全解析(四),Android 中使用 Dagger 2

发表于 2017-06-08 | 分类于 Android | | 阅读次数

Dagger 2 完全解析系列:

Dagger 2 完全解析(一),Dagger 2 的基本使用与原理

Dagger 2 完全解析(二),进阶使用 Lazy、Qualifier、Scope 等

Dagger 2 完全解析(三),Component 的组织关系与 SubComponent

Dagger 2 完全解析(四),Android 中使用 Dagger 2

Dagger 2 完全解析(五),Kotlin 中使用 Dagger 2

Dagger 2 完全解析(六),dagger.android 扩展库的使用

本系列文章是基于 Google Dagger 2.11-rc2 版本

在理解了 Dagger 2 完全解析系列的前三篇文章后,可能还是会对在 Android 实际项目中如何使用 Dagger 2 有些疑问,本文以 GoogleSamples 的 android-architecture(mvp 分支) 为例,逐步说明如何在 ToDo 项目中使用 Dagger 2。

本文中代码示例的地址:https://github.com/JohnnyShieh/ToDo/tree/mvp

使用 Dagger 2 后的代码地址:https://github.com/JohnnyShieh/ToDo/tree/mvp-dagger2

Android 中使用 Dagger 2

为了具有代表性,我选择 android-architecture 中的 todo-mvp 作为例子,MVP 架构大家都比较熟悉。现在假设我们的 Android 项目为 ToDo,那么如何引入 Dagger 2 实现依赖注入?

阅读全文 »

Dagger 2 完全解析(三),Component 的组织关系与 SubComponent

发表于 2017-05-31 | 分类于 Android | | 阅读次数

Dagger 2 完全解析系列:

Dagger 2 完全解析(一),Dagger 2 的基本使用与原理

Dagger 2 完全解析(二),进阶使用 Lazy、Qualifier、Scope 等

Dagger 2 完全解析(三),Component 的组织关系与 SubComponent

Dagger 2 完全解析(四),Android 中使用 Dagger 2

Dagger 2 完全解析(五),Kotlin 中使用 Dagger 2

Dagger 2 完全解析(六),dagger.android 扩展库的使用

本系列文章是基于 Google Dagger 2.11-rc2 版本

理解前面两篇文章后,可以使用 Dagger 2 框架完成一个对象的依赖注入。但是在实际项目中有多个需要注入依赖的对象,也就是说会有多个 Component,它们之间会有相同的依赖,那么该如何处理它们之间的关系呢?

前言

先看下面一个场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Man {
@Inject
Car car;
public void goWork() {
...
car.go();
...
}
}
public class Friend {
@Inject
Car car; // 车是向 Man 借的
public void goSightseeing() {
...
car.go();
...
}
}

Man 有一辆车,Friend 没有车,但是他可以借 Man 的车出去游玩下,提供 Car 实例的CarModule不变,那么我们应该怎么设计 Component 呢?

阅读全文 »

Dagger 2 完全解析(二),进阶使用 Lazy、Qualifier、Scope 等

发表于 2017-05-25 | 分类于 Android | | 阅读次数

Dagger 2 完全解析系列:

Dagger 2 完全解析(一),Dagger 2 的基本使用与原理

Dagger 2 完全解析(二),进阶使用 Lazy、Qualifier、Scope 等

Dagger 2 完全解析(三),Component 的组织关系与 SubComponent

Dagger 2 完全解析(四),Android 中使用 Dagger 2

Dagger 2 完全解析(五),Kotlin 中使用 Dagger 2

Dagger 2 完全解析(六),dagger.android 扩展库的使用

本系列文章是基于 Google Dagger 2.11-rc2 版本

在上篇文章中介绍了 Dagger 2 的三个核心要素,但是在实际使用过程中,还需要 Layz 注入、Qualifier(限定符)、Scope(作用域)等作为补充,也是在 Dagger 2 进阶中必须要掌握的内容。下面由简入繁地讲解这几个概念,同时结合 Dagger 2 的编译时生成代码分析背后的原理(示例代码沿用第一篇的,建议先阅读第一篇)。

在分析 Qualifier(限定符)、Scope(作用域)之前,先介绍一些简单的概念: Lazy 和 Provider 注入。

Lazy (延迟注入)

有时我们想注入的依赖在使用时再完成初始化,加快加载速度,就可以使用注入Lazy<T>。只有在调用 Lazy 的 get() 方法时才会初始化依赖实例注入依赖。

阅读全文 »
1…678…16
Johnny Shieh

Johnny Shieh

我本微末,心向天空

76 日志
13 分类
43 标签
GitHub Weibo Gmail 简书
  • 热门系列
  • Dagger 完全解析(6)
  • AspectJ in Android(3)
  • Kotlin 写 Android 单元测试(4)
  • Kotlin 协程完全解析(5)
© 2015 - 2019 Johnny Shieh
访客数 访问量