Kotlin安卓应用添加URL读取代码后崩溃原因咨询
问题原因
你那行URL("https://www.sepehrfarm.ir/app/read.php?username=host&password=1111").readText()是同步网络请求,安卓系统明确禁止在主线程(也就是onCreate所在的UI线程)里执行耗时的网络操作——主线程要负责渲染界面、响应用户操作,同步网络请求会直接阻塞主线程,触发系统的StrictMode检测机制,导致应用启动时直接崩溃。
额外逻辑问题
另外你的代码逻辑也不符合需求:现在是应用刚启动就发起固定账号密码的网络请求,再根据结果绑定按钮点击事件,但实际应该是用户输入账号密码后点击按钮,才发起网络请求验证,再弹出对应对话框,而不是启动时就请求固定参数。
修复代码示例(用Kotlin协程)
先确保项目已引入协程依赖(新建安卓项目默认已包含),修改代码如下:
package com.example.test1 import android.app.AlertDialog import android.content.DialogInterface import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.net.URL class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val username = findViewById<EditText>(R.id.etUserName) val password = findViewById<EditText>(R.id.etPassword) val btn = findViewById<Button>(R.id.button) // 用户点击按钮时才执行网络请求 btn.setOnClickListener { val inputUsername = username.text.toString().trim() val inputPassword = password.text.toString().trim() // 用协程在IO线程执行网络请求,避免阻塞主线程 GlobalScope.launch(Dispatchers.Main) { val response = withContext(Dispatchers.IO) { runCatching { URL("https://www.sepehrfarm.ir/app/read.php?username=$inputUsername&password=$inputPassword").readText() }.getOrNull() // 捕获网络异常,防止应用崩溃 } // 根据响应内容构建对话框 val dialogBuilder = AlertDialog.Builder(this@MainActivity) .setTitle("登录结果") .setIcon(R.mipmap.ic_launcher) .setPositiveButton("OK") { _, _ -> Toast.makeText(this@MainActivity, "已确认", Toast.LENGTH_SHORT).show() } if (response == "okay") { dialogBuilder.setMessage("登录成功") } else { dialogBuilder.setMessage("登录失败或网络异常") } dialogBuilder.show() } } } }
关键修改点
- 把网络请求移到按钮点击事件内,符合用户操作流程;
- 用
Dispatchers.IO线程执行网络请求,这是安卓专门处理IO操作的线程池,不会阻塞主线程; - 用
runCatching捕获网络异常(比如无网络、服务器错误等),避免应用崩溃; - 用
withContext切回主线程更新UI(对话框、Toast必须在主线程执行)。
内容的提问来源于stack exchange,提问作者Amir Elahi
相关产品推荐
相关产品推荐

