mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-16 03:32:38 +08:00
perf: update ktor, kotlin
This commit is contained in:
parent
8cca22d697
commit
2ae5698624
|
@ -5,10 +5,10 @@ import android.content.Intent
|
||||||
import com.blankj.utilcode.util.LogUtils
|
import com.blankj.utilcode.util.LogUtils
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.serialization.kotlinx.json.json
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
import io.ktor.server.application.call
|
|
||||||
import io.ktor.server.application.install
|
import io.ktor.server.application.install
|
||||||
import io.ktor.server.cio.CIO
|
import io.ktor.server.cio.CIO
|
||||||
import io.ktor.server.cio.CIOApplicationEngine
|
import io.ktor.server.cio.CIOApplicationEngine
|
||||||
|
import io.ktor.server.engine.EmbeddedServer
|
||||||
import io.ktor.server.engine.embeddedServer
|
import io.ktor.server.engine.embeddedServer
|
||||||
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
|
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
|
||||||
import io.ktor.server.request.receive
|
import io.ktor.server.request.receive
|
||||||
|
@ -22,6 +22,7 @@ import io.ktor.server.routing.route
|
||||||
import io.ktor.server.routing.routing
|
import io.ktor.server.routing.routing
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.MainScope
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
@ -57,19 +58,21 @@ import java.io.File
|
||||||
|
|
||||||
|
|
||||||
class HttpService : Service() {
|
class HttpService : Service() {
|
||||||
private val scope = CoroutineScope(Dispatchers.Default)
|
private val scope = MainScope()
|
||||||
|
private val httpServerPortFlow = storeFlow.map(scope) { s -> s.httpServerPort }
|
||||||
|
|
||||||
|
private var server: EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>? =
|
||||||
|
null
|
||||||
|
|
||||||
private var server: CIOApplicationEngine? = null
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
isRunning.value = true
|
isRunning.value = true
|
||||||
localNetworkIpsFlow.value = getIpAddressInLocalNetwork()
|
localNetworkIpsFlow.value = getIpAddressInLocalNetwork()
|
||||||
val httpServerPortFlow = storeFlow.map(scope) { s -> s.httpServerPort }
|
|
||||||
scope.launchTry(Dispatchers.IO) {
|
scope.launchTry(Dispatchers.IO) {
|
||||||
httpServerPortFlow.collect { port ->
|
httpServerPortFlow.collect { port ->
|
||||||
server?.stop()
|
server?.stop()
|
||||||
server = try {
|
server = try {
|
||||||
createServer(port).apply { start() }
|
scope.createServer(port).apply { start() }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
LogUtils.d("HTTP服务启动失败", e)
|
LogUtils.d("HTTP服务启动失败", e)
|
||||||
null
|
null
|
||||||
|
@ -86,16 +89,11 @@ class HttpService : Service() {
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
scope.cancel()
|
||||||
isRunning.value = false
|
isRunning.value = false
|
||||||
localNetworkIpsFlow.value = emptyList()
|
localNetworkIpsFlow.value = emptyList()
|
||||||
|
if (storeFlow.value.autoClearMemorySubs) {
|
||||||
scope.launchTry(Dispatchers.IO) {
|
deleteSubscription(LOCAL_HTTP_SUBS_ID)
|
||||||
server?.stop()
|
|
||||||
if (storeFlow.value.autoClearMemorySubs) {
|
|
||||||
deleteSubscription(LOCAL_HTTP_SUBS_ID)
|
|
||||||
}
|
|
||||||
delay(3000)
|
|
||||||
scope.cancel()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,95 +148,93 @@ private val httpSubsItem by lazy {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createServer(port: Int): CIOApplicationEngine {
|
private fun CoroutineScope.createServer(port: Int) = embeddedServer(CIO, port) {
|
||||||
return embeddedServer(CIO, port) {
|
install(KtorCorsPlugin)
|
||||||
install(KtorCorsPlugin)
|
install(KtorErrorPlugin)
|
||||||
install(KtorErrorPlugin)
|
install(ContentNegotiation) { json(keepNullJson) }
|
||||||
install(ContentNegotiation) { json(keepNullJson) }
|
routing {
|
||||||
routing {
|
get("/") { call.respondText(ContentType.Text.Html) { "<script type='module' src='$SERVER_SCRIPT_URL'></script>" } }
|
||||||
get("/") { call.respondText(ContentType.Text.Html) { "<script type='module' src='$SERVER_SCRIPT_URL'></script>" } }
|
route("/api") {
|
||||||
route("/api") {
|
// Deprecated
|
||||||
// Deprecated
|
get("/device") { call.respond(DeviceInfo.instance) }
|
||||||
get("/device") { call.respond(DeviceInfo.instance) }
|
|
||||||
|
|
||||||
post("/getServerInfo") { call.respond(ServerInfo()) }
|
post("/getServerInfo") { call.respond(ServerInfo()) }
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
get("/snapshot") {
|
get("/snapshot") {
|
||||||
val id = call.request.queryParameters["id"]?.toLongOrNull()
|
val id = call.request.queryParameters["id"]?.toLongOrNull()
|
||||||
?: throw RpcError("miss id")
|
?: throw RpcError("miss id")
|
||||||
val fp = File(SnapshotExt.getSnapshotPath(id))
|
val fp = File(SnapshotExt.getSnapshotPath(id))
|
||||||
if (!fp.exists()) {
|
if (!fp.exists()) {
|
||||||
throw RpcError("对应快照不存在")
|
throw RpcError("对应快照不存在")
|
||||||
}
|
|
||||||
call.respondFile(fp)
|
|
||||||
}
|
}
|
||||||
post("/getSnapshot") {
|
call.respondFile(fp)
|
||||||
val data = call.receive<ReqId>()
|
}
|
||||||
val fp = File(SnapshotExt.getSnapshotPath(data.id))
|
post("/getSnapshot") {
|
||||||
if (!fp.exists()) {
|
val data = call.receive<ReqId>()
|
||||||
throw RpcError("对应快照不存在")
|
val fp = File(SnapshotExt.getSnapshotPath(data.id))
|
||||||
}
|
if (!fp.exists()) {
|
||||||
call.respond(fp)
|
throw RpcError("对应快照不存在")
|
||||||
}
|
}
|
||||||
|
call.respond(fp)
|
||||||
|
}
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
get("/screenshot") {
|
get("/screenshot") {
|
||||||
val id = call.request.queryParameters["id"]?.toLongOrNull()
|
val id = call.request.queryParameters["id"]?.toLongOrNull()
|
||||||
?: throw RpcError("miss id")
|
?: throw RpcError("miss id")
|
||||||
val fp = File(SnapshotExt.getScreenshotPath(id))
|
val fp = File(SnapshotExt.getScreenshotPath(id))
|
||||||
if (!fp.exists()) {
|
if (!fp.exists()) {
|
||||||
throw RpcError("对应截图不存在")
|
throw RpcError("对应截图不存在")
|
||||||
}
|
|
||||||
call.respondFile(fp)
|
|
||||||
}
|
}
|
||||||
post("/getScreenshot") {
|
call.respondFile(fp)
|
||||||
val data = call.receive<ReqId>()
|
}
|
||||||
val fp = File(SnapshotExt.getScreenshotPath(data.id))
|
post("/getScreenshot") {
|
||||||
if (!fp.exists()) {
|
val data = call.receive<ReqId>()
|
||||||
throw RpcError("对应截图不存在")
|
val fp = File(SnapshotExt.getScreenshotPath(data.id))
|
||||||
}
|
if (!fp.exists()) {
|
||||||
call.respondFile(fp)
|
throw RpcError("对应截图不存在")
|
||||||
}
|
}
|
||||||
|
call.respondFile(fp)
|
||||||
|
}
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
get("/captureSnapshot") {
|
get("/captureSnapshot") {
|
||||||
call.respond(captureSnapshot())
|
call.respond(captureSnapshot())
|
||||||
}
|
}
|
||||||
post("/captureSnapshot") {
|
post("/captureSnapshot") {
|
||||||
call.respond(captureSnapshot())
|
call.respond(captureSnapshot())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
get("/snapshots") {
|
get("/snapshots") {
|
||||||
call.respond(DbSet.snapshotDao.query().first())
|
call.respond(DbSet.snapshotDao.query().first())
|
||||||
}
|
}
|
||||||
post("/getSnapshots") {
|
post("/getSnapshots") {
|
||||||
call.respond(DbSet.snapshotDao.query().first())
|
call.respond(DbSet.snapshotDao.query().first())
|
||||||
}
|
}
|
||||||
|
|
||||||
post("/updateSubscription") {
|
post("/updateSubscription") {
|
||||||
val subscription =
|
val subscription =
|
||||||
RawSubscription.parse(call.receiveText(), json5 = false)
|
RawSubscription.parse(call.receiveText(), json5 = false)
|
||||||
.copy(
|
.copy(
|
||||||
id = LOCAL_HTTP_SUBS_ID,
|
id = LOCAL_HTTP_SUBS_ID,
|
||||||
name = "内存订阅",
|
name = "内存订阅",
|
||||||
version = 0,
|
version = 0,
|
||||||
author = "@gkd-kit/inspect"
|
author = "@gkd-kit/inspect"
|
||||||
)
|
)
|
||||||
updateSubscription(subscription)
|
updateSubscription(subscription)
|
||||||
DbSet.subsItemDao.insert((subsItemsFlow.value.find { s -> s.id == httpSubsItem.id }
|
DbSet.subsItemDao.insert((subsItemsFlow.value.find { s -> s.id == httpSubsItem.id }
|
||||||
?: httpSubsItem).copy(mtime = System.currentTimeMillis()))
|
?: httpSubsItem).copy(mtime = System.currentTimeMillis()))
|
||||||
call.respond(RpcOk())
|
call.respond(RpcOk())
|
||||||
}
|
}
|
||||||
post("/execSelector") {
|
post("/execSelector") {
|
||||||
if (!A11yService.isRunning.value) {
|
if (!A11yService.isRunning.value) {
|
||||||
throw RpcError("无障碍没有运行")
|
throw RpcError("无障碍没有运行")
|
||||||
}
|
|
||||||
val gkdAction = call.receive<GkdAction>()
|
|
||||||
call.respond(A11yService.execAction(gkdAction))
|
|
||||||
}
|
}
|
||||||
|
val gkdAction = call.receive<GkdAction>()
|
||||||
|
call.respond(A11yService.execAction(gkdAction))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ suspend fun uploadFileToGithub(
|
||||||
}))
|
}))
|
||||||
}.body<UploadPoliciesAssetsResponse>()
|
}.body<UploadPoliciesAssetsResponse>()
|
||||||
|
|
||||||
|
val byteArray = file.readBytes()
|
||||||
// upload to s3
|
// upload to s3
|
||||||
client.post(policiesResp.upload_url) {
|
client.post(policiesResp.upload_url) {
|
||||||
setCommonHeaders(cookie)
|
setCommonHeaders(cookie)
|
||||||
|
@ -91,13 +92,13 @@ suspend fun uploadFileToGithub(
|
||||||
policiesResp.form.forEach { (key, value) ->
|
policiesResp.form.forEach { (key, value) ->
|
||||||
append(key, value)
|
append(key, value)
|
||||||
}
|
}
|
||||||
append("file", file.readBytes(), Headers.build {
|
append("file", byteArray, Headers.build {
|
||||||
append(HttpHeaders.ContentType, "application/x-zip-compressed")
|
append(HttpHeaders.ContentType, "application/x-zip-compressed")
|
||||||
append(HttpHeaders.ContentDisposition, "filename=\"file.zip\"")
|
append(HttpHeaders.ContentDisposition, "filename=\"file.zip\"")
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
onUpload { bytesSentTotal, contentLength ->
|
onUpload { bytesSentTotal, contentLength ->
|
||||||
listener(bytesSentTotal / contentLength.toFloat())
|
listener(bytesSentTotal / (contentLength ?: byteArray.size).toFloat())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,8 @@ data class NewVersion(
|
||||||
val versionName: String,
|
val versionName: String,
|
||||||
val changelog: String,
|
val changelog: String,
|
||||||
val downloadUrl: String,
|
val downloadUrl: String,
|
||||||
|
val fileSize: Long,
|
||||||
val versionLogs: List<VersionLog> = emptyList(),
|
val versionLogs: List<VersionLog> = emptyList(),
|
||||||
val fileSize: Long? = null,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@ -97,12 +97,12 @@ private fun UpdateStatus.startDownload(viewModel: MainViewModel, newVersion: New
|
||||||
job = viewModel.viewModelScope.launch(Dispatchers.IO) {
|
job = viewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val channel = client.get(URI(UPDATE_URL).resolve(newVersion.downloadUrl).toString()) {
|
val channel = client.get(URI(UPDATE_URL).resolve(newVersion.downloadUrl).toString()) {
|
||||||
onDownload { bytesSentTotal, contentLength ->
|
onDownload { bytesSentTotal, _ ->
|
||||||
// contentLength 在某些机型上概率错误
|
// contentLength 在某些机型上概率错误
|
||||||
val downloadStatus = downloadStatusFlow.value
|
val downloadStatus = downloadStatusFlow.value
|
||||||
if (downloadStatus is LoadStatus.Loading) {
|
if (downloadStatus is LoadStatus.Loading) {
|
||||||
downloadStatusFlow.value = LoadStatus.Loading(
|
downloadStatusFlow.value = LoadStatus.Loading(
|
||||||
bytesSentTotal.toFloat() / (newVersion.fileSize ?: contentLength)
|
bytesSentTotal.toFloat() / (newVersion.fileSize)
|
||||||
)
|
)
|
||||||
} else if (downloadStatus is LoadStatus.Failure) {
|
} else if (downloadStatus is LoadStatus.Failure) {
|
||||||
// 提前终止下载
|
// 提前终止下载
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
[versions]
|
[versions]
|
||||||
kotlin = "2.0.20"
|
kotlin = "2.0.21"
|
||||||
ksp = "2.0.20-1.0.25"
|
ksp = "2.0.21-RC-1.0.25"
|
||||||
android = "8.7.0"
|
android = "8.7.0"
|
||||||
compose = "1.7.3"
|
compose = "1.7.3"
|
||||||
rikka = "4.4.0"
|
rikka = "4.4.0"
|
||||||
room = "2.6.1"
|
room = "2.6.1"
|
||||||
paging = "3.3.2"
|
paging = "3.3.2"
|
||||||
ktor = "2.3.12"
|
ktor = "3.0.0"
|
||||||
destinations = "2.1.0-beta12"
|
destinations = "2.1.0-beta12"
|
||||||
coil = "2.7.0"
|
coil = "2.7.0"
|
||||||
shizuku = "13.1.5"
|
shizuku = "13.1.5"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user