2018-05-26

Kotlin DSL 应用

kotlin 宣传时的一个卖点就是 dsl

使用 kotlin ,配合 function literals with receiver 特性可以构建类型安全,静态类型的 builder

dsl 能做什么? Android 的 anko 库是一个非常好的例子,anko 提出使用 kotlin dsl 代替 xml 书写布局。

各种优势:

  • It is not typesafe;
  • It is not null-safe;
  • It forces you to write almost the same code for every layout you make;
  • XML is parsed on the device wasting CPU time and battery;
  • Most of all, it allows no code reuse.

ps. 一个问题,就是预览布局效果,xml 毕竟是从 android 最初一路走过来的,目前的表现没有太大问题;anko 刚起步,去年刚用时官方提供的预览插件基本不可以,不过看最近这个插件 (18.05.15) 有更新,有时间试下。

好,扯了这么多,其实我只是想说…终于在代码里用上这个特性了 23333

贴一下

1
2
3
4
5
6
private fun webPage(init: WXWebpageObject.() -> Unit): WXWebpageObject = WXWebpageObject().apply(init)
private suspend fun mediaMessage(init: suspend WXMediaMessage.() -> Unit): WXMediaMessage = WXMediaMessage().apply { init() }
private suspend fun image(init: suspend WXImageObject.() -> Unit): WXImageObject = WXImageObject().apply { init() }
private suspend fun miniProgram(init: suspend WXMiniProgramObject.() -> Unit): WXMiniProgramObject = WXMiniProgramObject().apply { init() }
private suspend fun wechatRequestBuilder(init: suspend SendMessageToWX.Req.() -> Unit): SendMessageToWX.Req = SendMessageToWX.Req().apply { init() }
private fun SendMessageToWX.Req.send() = WXApi.wxApi.sendReq(this)

国内这些分享集成真是要了老命,难用的一笔,说多了都是泪。
这块使用 dsl 构建分享 Message,配合 coroutines 异步请求网络数据,感觉上是不是好(bing)了(mei)点(you),安利一波

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 private fun shareMiniProgram(webUrl: String, path: String, title: String, description: String,
image: String) = async(UI) {
wechatRequestBuilder {
message = mediaMessage {
mediaObject = miniProgram {
webpageUrl = webUrl
miniprogramType = WXMiniProgramObject.MINIPTOGRAM_TYPE_RELEASE
userName = WECHAT_USER_NAME
this.path = path
}

Application.app?.toast("download image")
val data = async(CommonPool) {
ImageLoader.loadImageSync(Application.app, image)
}.await().ifNull {
Application.app?.toast("image load failed")
} ?: return@mediaMessage

val bitmap = data.takeIf {
data.wechatSize() < 120 * 1024
} ?: data.scale((120 * 1024f) / data.wechatSize())

this.title = title
this.description = description
thumbData = bitmap.toByteArray()
transaction = generateShareId()
}
scene = SendMessageToWX.Req.WXSceneSession
}.send()
}

赠品

1
2
3
4
// 微信图片处理
https://gist.github.com/tiiime/8673ddd97320cf18a468140add036641
// ifNull
https://gist.github.com/tiiime/9a2edb18f7f214b42d24b50ec28d2f46