Android中Ktor等HTTP请求AS内正常,真机/模拟器失效求助
解决方案
1. 修复HTTP请求未执行的问题
你的main()函数是Kotlin独立程序的入口,在Android应用环境中不会自动执行——Android Studio里能运行是因为IDE把它当成了普通Kotlin脚本执行,但在APK中这个函数永远不会被调用,所以statusCode一直是初始值。
修改方式:将请求逻辑移到Activity的点击事件中,使用Android的协程作用域执行挂起函数:
package com.example.httprequesttest import android.os.Bundle import android.widget.Button import android.widget.TextView import androidx.activity.ComponentActivity import androidx.activity.enableEdgeToEdge import androidx.lifecycle.lifecycleScope import io.ktor.client.HttpClient import io.ktor.client.engine.android.Android import io.ktor.client.request.get import io.ktor.client.statement.HttpResponse import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { private lateinit var textView: TextView private lateinit var getButton: Button override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContentView(R.layout.activity_main) textView = findViewById(R.id.textView) getButton = findViewById(R.id.getButton) getButton.setOnClickListener { // 使用lifecycleScope绑定Activity生命周期,在主线程启动协程 lifecycleScope.launch { val statusCode = fetchStatusCode() textView.text = "status code : $statusCode" } } } // 封装请求逻辑为挂起函数 private suspend fun fetchStatusCode(): String { return try { val client = HttpClient(Android) val response: HttpResponse = client.get("https://ktor.io/") "status: ${response.status}".also { client.close() } } catch (e: Exception) { "Error: ${e.message}" } } }
2. 修复logback导致的崩溃问题
ch.qos.logback:logback-classic依赖使用了Android不支持的Java 9+ API(Class.getModule()),所以会抛出NoSuchMethodError。
解决方式:
- 在
build.gradle.kts中移除该依赖:
dependencies { // 移除这一行 // implementation("ch.qos.logback:logback-classic:1.5.6") // 保留其他Ktor依赖,如需日志可改用Android内置日志 implementation("io.ktor:ktor-client-logging:2.3.12") }
- 配置Ktor的Logging插件使用AndroidLogger(在创建HttpClient时添加):
import io.ktor.client.plugins.logging.Logging import io.ktor.client.plugins.logging.LogLevel import io.ktor.client.plugins.logging.AndroidLogger // 修改fetchStatusCode函数 private suspend fun fetchStatusCode(): String { return try { val client = HttpClient(Android) { install(Logging) { logger = AndroidLogger() // 输出日志到Logcat level = LogLevel.INFO } } val response: HttpResponse = client.get("https://ktor.io/") "status: ${response.status}".also { client.close() } } catch (e: Exception) { "Error: ${e.message}" } }
3. 修正网络安全配置
你的network_security_config.xml配置的domain是自己的包名com.example.httprequesttest,但请求的是https://ktor.io/,这个配置完全无效。
- 如果你的请求都是HTTPS,可以直接删除该配置文件,并移除
AndroidManifest.xml中对应的android:networkSecurityConfig属性——Android默认允许HTTPS请求。 - 如果需要允许HTTP请求(cleartext),则修改配置为:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <!-- 允许所有HTTP请求(仅测试用,正式环境建议指定具体域名) --> <base-config cleartextTrafficPermitted="true" /> <!-- 或者指定允许HTTP的具体域名 --> <!-- <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">your-target-domain.com</domain> </domain-config> --> </network-security-config>
额外注意事项
- 不要在主线程使用
runBlocking,会阻塞UI导致ANR(应用无响应),始终用lifecycleScope/viewModelScope等Android专用协程作用域。 - 确保
AndroidManifest.xml中的<uses-permission android:name="android.permission.INTERNET" />已经添加(你当前配置已满足)。
内容的提问来源于stack exchange,提问作者CS-Studios
相关产品推荐
相关产品推荐

