Benny Huo

学海无涯,其乐无穷

为什么需要这样一篇文章

我们知道 Kotlin 对 Jvm 的支持实在是太好了,以至于我们创建一个 Java 工程,配置一下 Kotlin 的编译插件和标准库就可以很轻松愉快的开始玩耍,什么互调用、什么单步调试都没有毛病——毕竟 KotlinJvm 与 Java 无论从使用上还是从生态上都尽可能的保持了一致,构建也主要用了 gradle,所以从 Java 到 Kotlin 的切换可谓是无缝衔接。

而 Kotlin 同样支持的 JavaScript 就似乎有点儿麻烦了,毕竟二者所处的生态差异略大,KotlinJs 仍然主要采用 gradle 构建,而 JavaScript 的话,例如 Node.js,就使用 npm/yarn 安装管理依赖了。想想可能还是有点儿别扭,你当然可以自己创建一个简单的 KotlinJs 工程,并且自己负责管理 node_modules,但那样的话,node_modules 的依赖并不会被 KotlinJs 直接依赖到,还需要管理 JavaScript 映射到 Kotlin 的接口依赖,例如 jQuery 在 Kotlinjs 侧就有一个接口库方便 Kotlin 以类型安全的方式调用,不过你还是要自己安装好 jQuery 才行,很麻烦对吧。

这一节我们将给大家展示如何搭建一个基于 Node.js 的相对完美的 KotlinJs 的开发环境,这个环境可以做到:

  • 依赖只需要在 Gradle 中统一管理即可,node_modules 会被自动安装
  • 右键运行 Kotlin 中的 main 函数,就像我们在 KotlinJvm 当中一样
  • 单步调试 Kotlin 代码,全程对 JavaScript 的编译结果无感知

基于这个工程,大家就可以很愉快的测试 KotlinJs 的特性啦,就像我们在 KotlinJvm 上面那样,毫无违和感。

阅读全文 »

今天的话题很简单,分享下也许对大家可以有帮助或者有启发。

1. 背景

一看题目,有点儿晕。看个例子马上就明白了:

1
2
3
4
5
6
7
8
9
10
abstract class EventBuilder() {
protected var retryLimit = 3

fun retryLimit(retryLimit: Int): EventBuilder {
this.retryLimit = retryLimit
return this
}

abstract fun build(): PollingEvent
}

我们有这么一个类,一看就是要写 Builder 模式。不过由于我们的这个 Event 的类型比较多,因此希望写一个父类,来一个子类感受下:

1
2
3
4
5
6
7
8
9
10
11
12
13
class DisposableEventBuilder : EventBuilder() {
private var delay: Long = 0L
fun delay(delay: Long): DisposableEventBuilder {
this.delay = delay
return this
}

override fun build() = object: DisposableEvent(name, delay){
override fun onDisposableEvent() {
callback.onEvent(this)
}
}
}

看上去也没啥大毛病,用一下吧:

1
2
3
DisposableEventBuilder().retryLimit(3)
.delay(60_000) // ERROR!!
.build()

我们调用完父类的 retryLimit 方法后,想要设置下 delay,结果发现没有这个方法。

“我 X,这什么玩意儿”,你嘟囔了一句。

阅读全文 »

0. 新年立个 Flag

首先祝各位小伙伴在新的中国年里找到属于自己的奋斗方向,凝聚自己的奋斗方法,实现自己的奋斗目标。

每年春节 0 点之后都喜欢随便做点儿自己喜欢的事情。曾经有一年就是在这个时间憋出了一篇晦涩难懂的协程的文章,所以今年需要在 Kotlin 协程上多写点儿文章,也许也可以写点儿 lib,总之公众号在这一年的发力点,协程算一个,应该也不会局限于 Java 虚拟机。

我前一阵子写过几次用 Kotlin Native 作为 JNI 的底层实现的文章。Kotlin Native 尽管可能还不是很完美,但就像它的负责人说的,后面的版本就需要来偿还技术债了,毕竟它从诞生开始就面临了类似于我们国内任何一款互联网产品一样的境遇,它如果不够快,也许就赶不上这波节奏了。可能各方面体验还没有那么好,但它的全貌已经完全呈现在我们面前,所以我们要做的就是帮助它,把生态建立起来。所以今年公众号也会把 Kotlin Native 作为一个重点,也许年底我能鼓捣出一个让 KN 写 JNI 变得很方便的 wrapper 呢,希望我时间会比较充裕吧。

阅读全文 »

大家一定用过 RxJava,也一定知道用 RxJava 发了个任务,任务还没结束页面就被关闭了,如果任务迟迟不回来,页面就会被泄露;如果任务后面回来了,执行回调更新 UI 的时候也会大概率空指针。

因此大家一定会用到 Uber 的开源框架 AutoDispose

阅读全文 »

上一篇文章我讲了用 @CName 这个神奇的注解,可以配置 Kotlin Native 函数在符号表中的名字,进而根据 Jni 静态绑定的规则来对应到 Java native 方法,但实际开发当中我们更喜欢用动态注册的方式,因为一方面不受名字的约束,不影响代码重构,函数名也相对美观,另一方面调用起来也相对高效,节省了静态绑定的查找过程。

阅读全文 »

我在之前写过一篇文章,讲如何用 Kotlin Native 编写 Native 代码通过 JNI 让 Java 调用。当时因为完全没有注意到 CName 这个神奇的东西的存在,所以那篇文章当中还是用 C wrapper 来做的调用。

后来,我发现根本不需要这么麻烦啊。

阅读全文 »

0. 题外话:Hadi 的插件

上周的 JetBrains 开发者大会,Hadi 的两个插件比较亮眼,这里有小伙伴如果没有听到最后一场,可能不知道它们是啥,它们分别是:

  • Nyan Process Bar
  • Presentation Assistant

也有同学问我ppt的,上周一的文章末尾有提供哈~

好了下面我们言归正传~

1. 描述下需求

前不久跟群里小伙伴讨论的时候,发现他们有一个需求,那就是在一个变量使用完之后要将其置为 null,但是呢,又不愿意将它声明为可空类型,这个需求实在是。。大概就像这样吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MainActivity: Activity {
lateinit var image: Bitmap

override fun onStart(){
super.onStart()
image = Bitmap.create(...)
}

override fun onStop(){
super.onStop()
image.recycle()
image = null // You cannot do that!!
}
}
阅读全文 »

难得取了这么正经的一个题目,根本不是我的风格啊︿( ̄︶ ̄)︿。

话说昨天去参加了一下 JetBrains 的开发者大会,因为我把钱都充点券买皮肤了,买不起门票( ̄. ̄),所以就选择在下午分会场做了一个 Kotlin 的分享来混入其中 (~ ̄▽ ̄)~

阅读全文 »

我在做 基于 GitHub App 业务深度讲解 Kotlin1.2高级特性与框架设计 这门课的时候,顺便做了一个注解处理器的框架,叫 Tieguanyin(铁观音),这个框架主要是用来解决 Activity 跳转时传参的问题,我们知道 Activity 如果需要参数,那么我们只能非常繁琐的使用 Intent 来传递,有了这个框架我们就可以省去这个麻烦的步骤。

在这里,框架的内容其实不是重点,重点是,它是一个注解处理器的项目。为了让它的作用尽可能的放大,我对原框架做了简化,做了这套课程。

阅读全文 »
0%