Kotlin实战经验

q
qqwuweiyi
楼主 (未名空间)
我们的APP大概500M downloading。所以应该算一个比较大型的,团队基本都用kotlin了

https://www.zhihu.com/question/37288009/answer/171576441

作者:娓娓道来
链接:https://www.zhihu.com/question/37288009/answer/171576441
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我的kotlin之旅,准备些写一个系列有update:两年前,老板正式要求所有新class必
须是Kotlin class。我们的app正是进变成Java和Kotlin混合存在,以Java为主导,慢
慢向Kotlin转化。Kotlin刚上手,那就是直接写Java,然后拷贝到Kotlin class 里面
,因为有自动convert的功能,勉强应付。如果是一个全新的class,那么直接先写Java然后在全部convert到Kotlin。我们的老板是非常好的一个人,第一个Kotlin class,
是他坐在我旁边一起改的。我们app的 code base 很大,全是Java,那会只是改改加加小的feature,平时真正要写Kotlin的很少,所以,开始的半年,Kotlin就是打酱油一
样用用。我不觉得有多好,而且觉得难用。现在我们的code从100%的Java变成了30%的
Java,Kotlin已经占的大壁江山,而且是老的没有接触到的那部分才是Java,只要在新版本中更新的的或者常用的全是Kotlin。用习惯了Kotlin,效率蹭蹭蹭提高啊。时不时会用到以前的Java code,用几下就觉得不方便,如果要在原来的Java code里面加新
code,几行还好,多一点就无法忍受,直接先把Java class转成Kotlin再说。记得中间,因为个人原因修了几个月的长假,长假之前还都是Java,长假之后全是Kotlin。一回到公司做的第一个feature是我最痛苦的,所有的新的class都是kotlin。Kotlin真的很缩略,老板很兴奋得说我们现在的code多么多么精简,好吧,但是,真的读不懂,好怀念Java,多么readable。写code更痛苦,坐在电脑门前半个小时,写不出几行,千言万语就是写不出来。有人会说,那还是可以先写Java在转化成Kotlin。但那个是初级阶段,大家都在学习。当前的阶段直接从Java转化到Kotlin的code已经不符合我们的要求了,因为直接写Kotlin更精简。Google I/O 宣布Kotlin正式成Android官方语言,大快人心,不觉就赞一下我们老板的先见之明啊。想当初要用Kotlin的时候,我还百般不愿。啰啰嗦嗦写了点感慨,下一篇正式讲讲一个java用“Convert to Kotlin”后如何优化
kotlin code。 Android Studio,转化Kotlin的功能很强大。如果在Kotlin的文件中,可以直接拷贝Java code到Kotlin中,自动转化。或者可以用“Convert Java File to Kotlin File” 可以自动把Java转化成Kotlin。转化完成后,不是说就好了,还需要优化很多东西。读者可以先了解一下Kotlin Null Safety 首先把所有的“!!”都去掉
。为什么要去掉“!!”?因为它会产生NullPointerException。如果你很喜欢NPE,
那就直接跳过这篇。Kotlin是Null Safety,它最重要的一个功能就是可以帮助app大幅度的减少NPE。开发Android app,NullPointerException,防不胜防。如何减少,我们举个例子。原始Javapublic class VideoView extends FrameLayout {
MediaPlayer mediaPlayer = null;
......

public void pause() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
}
转化成Kotlin以后 class VideoView : FrameLayout {
var mediaPlayer: MediaPlayer? = null
......

fun pause() {
if (mediaPlayer!!.isPlaying) {
mediaPlayer!!.pause()
}
}
}
其中 mediaPlayer 是mutable的,也就是说它的值是会改变的。所以这里的
mediaPlayer不能是Null, 否则就会产生NPE。Kotlin帮我们找到了原来Java的一个NPE。那么我们要删掉“!!”,应该怎么做呢? 加上if (mediaPlayer != null),可以,但最烦的就是null check。Kotlin可以这样写:mediaPlayer?.let { // 如果
mediaPlayer不是NULL,那么执行if。等同于Null Check。
if (mediaPlayer.isPlaying) {
mediaPlayer.pause()
}
}
这样以后还不对。为什么,因为mediaPlayer是mutable的,它的值是会改变的,有这样的情况,“mediaPlayer?.let{}” null check 的时候它不是null,但当运行“
mediaPlayer.isPlaying”的时候如果mediaPlayer的值变化,正好变成null了,那还是会发生NPE。那如何再改呢?class VideoView : FrameLayout {
var mediaPlayer: MediaPlayer? = null
......

fun pause() {
val mediaPlayer = mediaPlayer
mediaPlayer?.let {
if (mediaPlayer.isPlaying) {
mediaPlayer.pause()
}
}
}
其中:val mediaPlayer = mediaPlayer
前面的mediaPlayer是一个新的variable,它是read-only,一旦赋值以后是不会变得,而且是local的。后面的mediaPlayer 是上面原来的field变量。这样就最大程度的减少了NPE。上面的Kotlin code还可以做的一个改进就是用 lambda,实际上这里就是做了和上面val mediaPlayer = mediaPlayer 一样的事情。如下:class VideoView :
FrameLayout {
var mediaPlayer: MediaPlayer? = null
......

fun pause() {
mediaPlayer?.let {
if (it.isPlaying) {
it.pause()
}
}
}
lambda以后再详述。为什么这里我要把这个拿出来说,因为这个是在转化成Kotlin之后常常碰到的一个问题。 val mediaPlayer = mediaPlayer //也可以写成this.
mediaPlayer
3. Kotlin 精简,先说一下,不用动脑筋就可以省去的行数。第一: single
expression function。可以参考Kotlin functions 的single expression function。图片贴不上来,直接看链接吧。意思是:如果一个函数里面只有一个语句,那么可以直接用“=“简化。
举个例子,常见的custom adpater里面都会包括这两个Methods,Java共12行。@
Override
public int getItemCount() {
return items.size() + 1;
}

@Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
} else {
return TYPE_ITEM;
}
}
Kotlin 可以这样写,2行就可以。override fun getItemCount() = items.size + 1

override fun getItemViewType(position: Int) = if (position == 0) TYPE_HEADER else TYPE_ITEM
第二:多用 when
Mac上option + enter,“Project quick fix ”,直接可以把 if 转成 when 语句。
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
if (viewType == TYPE_VIDEO_ITEM) {
return new VideoItemViewHolder(parent);
} else if (viewType == TYPE_IMAGE_ITEM) {
return new ImageItemViewHolder(parent);
} else {
return new HeaderViewHolder(parent);
}
return null;
}
转化成Kotlin:override fun onCreateViewHolder(parent: ViewGroup, viewType:
Int): RecyclerView.ViewHolder? {
return when (viewType) {
TYPE_VIDEO_ITEM -> VideoViewHolder(parent)
TYPE_IMAGE_ITEM -> ImageItemViewHolder(parent)
else -> HeaderViewHolder(parent)
}
}
暂时想到这两个就写到这里。对于我们动不动就几百上千行的文件,省一点是一点,我觉得还是挺好的。不熟悉的时候,看着觉得太省略;熟悉了,一目十行,效率啊
w
wdong
2 楼
关键:

Kotlin真的很缩略,老板很兴奋得说我们现在的code多么多么精简,好吧,但是,真的读不懂,好怀念Java,多么readable。

【 在 qqwuweiyi (娓娓) 的大作中提到: 】
我们的APP大概500M downloading。所以应该算一个比较大型的,团队基本都用
kotlin了
https://www.zhihu.com/question/37288009/answer/171576441
作者:娓娓道来
链接:https://www.zhihu.com/question/37288009/answer/171576441
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我的kotlin之旅,准备些写一个系列有update:两年前,老板正式要求所有新class必
须是Kotlin class。我们的app正是进变成Java和Kotlin混合存在,以Java为主导,慢
慢向Kotlin转化。Kotlin刚上手,那就是直接写Java,然后拷贝到Kotlin class 里面
,因为有自动convert的功能,勉强应付。如果是一个全新的class,那么直接先写
Java
...................
g
guvest
3 楼
除了kotlin可以做大项目,没硬伤之外,没什么干货。

情怀太多了。语法之间的转换多数是很简单的代数问题。
目测作者没少读 thinking in xxx, 快成残废了,5年内会翻转在翻转。

【 在 wdong (万事休) 的大作中提到: 】
关键:
Kotlin真的很缩略,老板很兴奋得说我们现在的code多么多么精简,好吧,但是,真的
读不懂,好怀念Java,多么readable。
kotlin了
Java
g
guvest
4 楼
Android Java这个问题的根本其实就是GooG vs Oracle啊。
可怜的马工。。。
【 在 qqwuweiyi (娓娓) 的大作中提到: 】
我们的APP大概500M downloading。所以应该算一个比较大型的,团队基本都用
kotlin了
https://www.zhihu.com/question/37288009/answer/171576441
作者:娓娓道来
链接:https://www.zhihu.com/question/37288009/answer/171576441
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我的kotlin之旅,准备些写一个系列有update:两年前,老板正式要求所有新class必
须是Kotlin class。我们的app正是进变成Java和Kotlin混合存在,以Java为主导,慢
慢向Kotlin转化。Kotlin刚上手,那就是直接写Java,然后拷贝到Kotlin class 里面
,因为有自动convert的功能,勉强应付。如果是一个全新的class,那么直接先写
Java
...................
n
nacst23
5 楼
可怜什么,
新需求, 新的 head count 啊,
都不变, 怎么涨工资

【 在 guvest (我爱你老婆Anna) 的大作中提到: 】
Android Java这个问题的根本其实就是GooG vs Oracle啊。
可怜的马工。。。
kotlin了
Java
l
longtian
6 楼
impact就是这么出来的

【 在 nacst23 (cnc) 的大作中提到: 】
可怜什么,
新需求, 新的 head count 啊,
都不变, 怎么涨工资
q
qqwuweiyi
7 楼
刚开始的是比较直接一点的,后面还会更新high order function,lambda之类,看时间
吧,不过我也不是牛人,抛砖引玉
w
walkrandom
8 楼
楼主,牛啊。
牛人都能预测需求。

海龟的本钱攒下来了。开个Kotlin培训班,没有问题的。
s
stdio
9 楼
看着很乱,到底是在夸还是在踩?
f
fantasist
10 楼
举个例子,常见的custom adpater里面都会包括这两个Methods,Java共12行。@
Override
public int getItemCount() {
return items.size() + 1;
}

@Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
} else {
return TYPE_ITEM;
}
}
Kotlin 可以这样写,2行就可以。override fun getItemCount() = items.size + 1

override fun getItemViewType(position: Int) = if (position == 0) TYPE_HEADERelse TYPE_ITEM

=====
比如这个例子纯粹是语法糖,并没有任何实际好处。关心省几行代码这种小事,目光太短浅了吧。我觉得作者举的几个例子都不怎么样,看不出kotlin比java好在哪。
f
fantasist
11 楼
我也觉得G选kotlin纯粹是为了摆脱oracle而强行换一个语言,又要保证跟jvm和已有
java代码的兼容性,未来不知道会有多少坑。
【 在 guvest (我爱你老婆Anna) 的大作中提到: 】
Android Java这个问题的根本其实就是GooG vs Oracle啊。
可怜的马工。。。
kotlin了
Java
x
xyz14
12 楼
我觉得主要是如果能够很方便的写fun,很多java的pattern就不需要了,写起来就会自由很多,对于牛人就是提高生产力。

当然如果你是和一堆烂人工作,flexible的语言就会很痛苦。所以java和阿三,在某种意义下,是共生的关系。

【 在 fantasist (一) 的大作中提到: 】
举个例子,常见的custom adpater里面都会包括这两个Methods,Java共12行。@
Override
public int getItemCount() {
return items.size() + 1;
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
} else {
...................
b
brainless
13 楼
kotlin最大的区别,就是不是纯OOD语言了

【 在 qqwuweiyi (娓娓) 的大作中提到: 】
我们的APP大概500M downloading。所以应该算一个比较大型的,团队基本都用
kotlin了
https://www.zhihu.com/question/37288009/answer/171576441
作者:娓娓道来
链接:https://www.zhihu.com/question/37288009/answer/171576441
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我的kotlin之旅,准备些写一个系列有update:两年前,老板正式要求所有新class必
须是Kotlin class。我们的app正是进变成Java和Kotlin混合存在,以Java为主导,慢
慢向Kotlin转化。Kotlin刚上手,那就是直接写Java,然后拷贝到Kotlin class 里面
,因为有自动convert的功能,勉强应付。如果是一个全新的class,那么直接先写
Java
...................