Kotlin定时任务

Kotlin的定时任务主要通过Timer().schedule()和TimerTask()来实现

schedule()需要三个参数 可执行的方法、开始时间、执行间隔时间(毫秒),参考源码获取更多Timer().schedule()的信息

1
2
3
4
5
6
7
8
fun main(){
Timer().schedule(
object: TimerTask(){
override fun run() {
println("每1秒钟打印一次,Date()表示立刻开始")
}
}, Date(),1000)
}

获取每日新闻图片

这一部分属于简单的API调用操作。分为 请求API->解析结果->获取资源链接->下载资源。主要使用的工具类OKhttp4和Alibaba JSON2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//获取新闻图片url
val DAILYNEWSAPI = "https://v2.alapi.cn/api/zaobao"
val APITOKEN = "**************"
val params = mutableMapOf("token" to APITOKEN,"format" to "json")
val headers = Headers.headersOf("Content-Type" , "application/x-www-form-urlencoded")
val result = OkHttpClientUtil.getHttpRespondToString(DAILYNEWSAPI, params, headers)
val imageUrl = JSON.parseObject(result).getJSONObject("data").getString("image")
println(imageUrl)
var imagePath: String
//判断系统适配下载路径
if (System.getProperty("os.name").lowercase().contains("linux")) { imagePath = "/root/file/resources/img/mirai/" }else{ imagePath = "./" }
//下载图片文件到本地
val imageTitle: String = LocalDate.now().toString()
val imageFile: File = OkHttpClientUtil.saveImageFile(imagePath,imageUrl,imageTitle,".png")

OkHttpClientUtil.kt

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
object OkHttpClientUtil {

private val client = OkHttpClient()

fun getHttpRespondToString(url: String,params: MutableMap<String,String>,headers: Headers): String {
val httpUrl = url.toHttpUrl().newBuilder()
var responseStr = ""
if (params != null) {
for (param in params){
httpUrl.addQueryParameter(param.key,param.value)
}
}
val request = Request.Builder().url(httpUrl.build()).headers(headers).build();
try {

val response = client.newCall(request).execute()
responseStr = response.body!!.string()
if(response.body != null) {
response.body!!.close();
}
}catch (e: IOException){
return "Get Request Error!"
}
return responseStr
}

/**
* 在网络上下载图片到本地,使用的是okhttp
* @param imageUrl 图片链接
* @param imageTitle 图片标题
* @param imageFormat 图片文件后缀
* @param imagePath 保存地址
* @return File
* @throws IOException IO异常
*/

fun saveImageFile(imagePath: String,imageUrl: String,imageTitle: String,imageFormat: String): File{
val imageFile = File(imagePath + imageTitle + imageFormat)
val request = Request.Builder().url(imageUrl).build();
val fos: FileOutputStream
try {
fos = FileOutputStream(imageFile)
val response: Response = client.newCall(request).execute()
Objects.requireNonNull(response.body)?.bytes()?.let { fos.write(it) }
fos.close()
response.close()
} catch (e: IOException) {
e.printStackTrace()
}
return imageFile
}

}

狼宝应用实际开发

这段代码放在了StartBot.kt中 bot.login()之后 bot.join()之前的位置。

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
//明早9点
val date = LocalDateTime.parse("${LocalDate.now().plusDays(1)}090000", DateTimeFormatter.ofPattern("yyyy-MM-ddHHmmss"))
.atZone(ZoneId.systemDefault()).toInstant()
Timer().schedule(
object: TimerTask(){
override fun run(): Unit = runBlocking {
//获取open的群列表
val groupList = GroupService.getOpenGroups()
//获取新闻图片url
val DAILYNEWSAPI = "https://v2.alapi.cn/api/zaobao"
val APITOKEN = "vpu5ehavLNShzQ5a"
val params = mutableMapOf("token" to APITOKEN,"format" to "json")
val headers = Headers.headersOf("Content-Type" , "application/x-www-form-urlencoded")
val result = OkHttpClientUtil.getHttpRespondToString(DAILYNEWSAPI, params, headers)
val imageUrl = JSON.parseObject(result).getJSONObject("data").getString("image")
println(imageUrl)
var imagePath: String
//判断系统适配下载路径
if (System.getProperty("os.name").lowercase().contains("linux")) { imagePath = "/root/file/resources/img/mirai/" }else{ imagePath = "./" }
//下载图片文件到本地
val imageTitle: String = LocalDate.now().toString()
val imageFile: File = OkHttpClientUtil.saveImageFile(imagePath,imageUrl,imageTitle,".png")
groupList.forEach { group: Group ->
println(group.number)
bot.getGroup(group.number)?.sendImage(imageFile)
}
}
}, Date.from(date),86400000) //开始于明早9点,间隔24小时执行一次

实际效果和结语

稳定上线了再说吧。