You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:24:07