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

Android Studio中WebView无法连接Socket.io服务器的问题

Android WebView无法连接Socket.io的问题

我有一份HTML文件,在电脑浏览器中可正常连接Socket.io服务器,但在Android Studio的WebView中运行时,无法与Socket.io建立连接。相关代码及已配置权限如下:

HTML代码

<!DOCTYPE html>
<html>
    <head>
        <title>Leaflet Popup Example</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="./leaflet/leaflet.css"/>
        <script src="./leaflet/leaflet.js"></script>
        <script src="./socket_io.js"></script>
    </head>
    <body>
        <div id="mapid" style="height: 100vh;"></div>
        <script>
            var socket = io("http://xxxxx:3000");

            var mymap = L.map('mapid').setView([39.9042, 32.6227], 5);

            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '&copy; OpenStreetMap contributors'
            }).addTo(mymap);
            var placedMarkers = [];
            socket.on("clientLocations", (data) => {
                placedMarkers.forEach(function(placedMarkers) {
                    mymap.removeLayer(placedMarkers);
                });
                placedMarkers = [];
                markers = data;
                var bounds = [];
                for (var i = 0; i < markers.length; i++) {
                    var marker = L.marker(markers[i].location).addTo(mymap);
                    placedMarkers.push(marker);

                    var popup = L.popup({
                    autoClose: false,
                    closeOnClick: false,
                    closeButton: false,
                    }).setContent(markers[i].name);

                    marker.bindPopup(popup).openPopup();
                    bounds.push(markers[i].location);
                }

                mymap.fitBounds(bounds, { padding: [100, 100], maxZoom: 100 });
            });
        </script>
    </body>
</html>

Kotlin代码

val webView: WebView = findViewById(R.id.web_view);
webView.settings.javaScriptEnabled = true;
webView.loadUrl("file:///android_asset/html/index.html")

已配置权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

解决方法

  • 完善WebView核心设置:Socket.io依赖DOM存储等特性,补充配置:
val webView: WebView = findViewById(R.id.web_view)
webView.settings.apply {
    javaScriptEnabled = true
    domStorageEnabled = true // Socket.io必须依赖的DOM存储功能
    allowFileAccess = true
    allowContentAccess = true
}
webView.loadUrl("file:///android_asset/html/index.html")
  • 允许明文HTTP请求:如果Socket.io服务器使用HTTP协议(非HTTPS),Android 9及以上系统默认禁止明文流量,需在AndroidManifest.xml的<application>标签中添加:
<application
    ...
    android:usesCleartextTraffic="true">
    ...
</application>
  • 匹配Socket.io版本:确保客户端socket_io.js的版本与服务器端Socket.io版本完全兼容,版本不匹配会直接导致连接失败。

  • 添加WebViewClient处理请求跳转:处理Socket.io连接过程中的重定向等请求:

webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
        url?.let { view?.loadUrl(it) }
        return true
    }
}
  • 验证网络可达性:确认测试设备能正常访问http://xxxxx:3000,可通过设备浏览器打开该地址,检查Socket.io握手接口是否正常响应。

内容的提问来源于stack exchange,提问作者Asidistaken

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:02:08