Android通过PHP从MySQL数据库获取数据时遭遇android.os.NetworkOnMainThreadException异常及多结果处理问题
解决你的Android-MySQL数据获取问题
嘿,我来帮你搞定这两个问题:
1. 解决NetworkOnMainThreadException错误
这个错误的核心原因很直白:Android不允许在主线程(UI线程)执行网络请求,你的代码里虽然用了Handler,但getMainLooper()意味着这个Handler的任务还是跑在主线程里,调用getPolls()发起网络请求自然就触发了这个异常。
修改方案:子线程执行网络请求,主线程更新UI
你可以用AsyncTask来封装网络请求和UI更新(Java项目里这个方式很实用),或者手动开线程配合runOnUiThread。下面是用AsyncTask修改后的代码:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_polls); ListView listView = findViewById(R.id.list_polls); ArrayList<String> titles = new ArrayList<>(); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, titles); listView.setAdapter(adapter); // 启动AsyncTask执行网络请求 new FetchPollsTask(titles, adapter).execute(); } // 自定义AsyncTask,负责网络请求和UI更新 private class FetchPollsTask extends AsyncTask<Void, Void, List<String>> { private ArrayList<String> titleList; private ArrayAdapter<String> adapter; public FetchPollsTask(ArrayList<String> titleList, ArrayAdapter<String> adapter) { this.titleList = titleList; this.adapter = adapter; } @Override protected List<String> doInBackground(Void... voids) { // 这里在子线程执行网络请求 try { URL url = new URL("http://192.168.1.8/getPolls.php"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); InputStream in = con.getInputStream(); BufferedReader r = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = r.readLine()) != null) { response.append(line); } // 解析JSON字符串为字符串数组 JSONArray jsonArray = new JSONArray(response.toString()); List<String> pollTitles = new ArrayList<>(); for (int i = 0; i < jsonArray.length(); i++) { pollTitles.add(jsonArray.getString(i)); } return pollTitles; } catch (Exception e) { e.printStackTrace(); return null; } } @Override protected void onPostExecute(List<String> result) { // 这里在主线程更新UI if (result != null) { titleList.clear(); titleList.addAll(result); adapter.notifyDataSetChanged(); // 通知适配器数据更新 } } }
2. 处理数据库多条结果的场景
你的PHP代码现在直接echo每条title,多条数据会连在一起(比如标题1标题2),Android根本没法拆分。正确的做法是返回JSON格式的数组,这样Android可以轻松解析。
修改后的PHP代码:
<?php // 设置响应头为JSON格式,让Android能正确识别 header('Content-Type: application/json'); $con = mysqli_connect("localhost", "root", "", "evote"); // 检查数据库连接是否成功,失败则返回空数组 if (!$con) { echo json_encode([]); exit; } $qu = "select title from polls"; // 只查询需要的title字段,减少数据传输 $result = mysqli_query($con, $qu); $titles = []; if (mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_assoc($result)) { $titles[] = $row['title']; } } // 输出JSON格式的标题数组 echo json_encode($titles); mysqli_close($con); ?>
额外注意事项
- 确保你的AndroidManifest.xml里添加了网络权限:
<uses-permission android:name="android.permission.INTERNET" />
- 测试时保证手机和运行PHP的服务器在同一个局域网内,
192.168.1.8这个IP要能正常访问。
内容的提问来源于stack exchange,提问作者Mah
相关产品推荐
相关产品推荐

