Android WebView - loadUrl 方法的长度限制

loadUrl 方法的长度限制

  1. 在 Android WebView 开发中,使用 loadUrl 方法执行 Iavascript 代码并传递数据时,数据长度是受到限制的

  2. 数据长度通常被限制为不能超过 2MB


loadUrl 方法的长度限制演示

1、准备阶段
(1)Web
  • loadUrl.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>loadUrl</title>
	</head>

	<body>
        <script>
			function printContentLength(content) {
				console.log("----- ", content.length);
			}
		</script>
    </body>
</html>
(2)Activity Layout
  • activity_load_url.xml
xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".LoadUrlActivity"
    tools:ignore="MissingConstraints">

    <WebView
        android:id="@+id/wv_container"
        android:layout_width="match_parent"
        android:layout_height="500dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(3)Activity Code
  • LoadUrlActivity.java
java 复制代码
public class LoadUrlActivity extends AppCompatActivity {

    public static final String TAG = LoadUrlActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_load_url);

        WebView wvContainer = findViewById(R.id.wv_container);

        wvContainer.loadUrl("file:///android_asset/webview/loadUrl.html");

        WebSettings webSettings = wvContainer.getSettings();
        webSettings.setJavaScriptEnabled(true);

        wvContainer.setWebViewClient(new WebViewClient() {

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);

                wvContainer.loadUrl("javascript:printContentLength('hello world')");
            }
        });
    }
}
2、测试记录
  1. 传递长度为 1MB 的数据
java 复制代码
String str = new String(new char[1024 * 1024]).replace("\0", "a");

wvContainer.loadUrl("javascript:printContentLength('" + str + "')");
复制代码
# 输出结果

-----  1048576
  1. 传递长度为 2MB 的数据
java 复制代码
String str = new String(new char[2 * 1024 * 1024]).replace("\0", "a");

wvContainer.loadUrl("javascript:printContentLength('" + str + "')");
复制代码
# 输出结果

(无)

优化方案

1、基本介绍
  1. 优先使用 evaluateJavascript 方法来执行 JavaScript 代码,它没有字符数限制,执行效率更高,并能获取 JavaScript 的返回值

  2. 如果仍然使用 loadUrl 方法来执行较长的 JavaScript 代码,可以分片传输数据

2、演示
(1)使用 evaluateJavascript 方法
  1. 传递长度为 1MB 的数据
java 复制代码
String str = new String(new char[1024 * 1024]).replace("\0", "a");

wvContainer.evaluateJavascript("printContentLength('" + str + "')", null);
复制代码
# 输出结果

-----  1048576
  1. 传递长度为 2MB 的数据
java 复制代码
String str = new String(new char[2 * 1024 * 1024]).replace("\0", "a");

wvContainer.evaluateJavascript("printContentLength('" + str + "')", null);
复制代码
# 输出结果

-----  2097152
(2)分片传输数据
  • 传递长度为 2MB 的数据
js 复制代码
let contents = null;

function printContentLength(content, chunkNum, chunkTotal) {
    if (contents == null) contents = [];
    contents.push(content);
    if (chunkNum != chunkTotal) return;
    console.log("----- ", contents.join("").length);
}
java 复制代码
String str = new String(new char[2 * 1024 * 1024]).replace("\0", "a");

// 分片传输字符串
int chunkSize = 1024 * 1024; // 1MB 分片
int chunkTotal = (int) Math.ceil((double) str.length() / chunkSize);
for (int i = 0; i < chunkTotal; i++) {
    int start = i * chunkSize;
    int end = Math.min(start + chunkSize, str.length());
    String chunk = str.substring(start, end);
    wvContainer.loadUrl(String.format("javascript:printContentLength('%s', %d, %d)",
            chunk, i + 1, chunkTotal));
}
复制代码
# 输出结果

-----  2097152
相关推荐
前端架构师-老李2 小时前
Maven安装以及环境变量配置(macOS)
java·macos·maven
Coffeeee2 小时前
面试被问到Compose的副作用不会,只怪我没好好学
android·kotlin·android jetpack
Greenland_122 小时前
Android Gralde补全计划 productFlavors多渠道打包(变体/多客户)
android
Just_Paranoid2 小时前
【TaskStackListener】Android 中用于监听和响应任务栈
android·ams·task·taskstack
权泽谦2 小时前
从零搭建一个 PHP 登录注册系统(含完整源码)
android·开发语言·php
带刺的坐椅2 小时前
(对标 Spring IA 和 LangChain4j)Solon AI & MCP v3.7.0, v3.6.4, v3.5.8 发布(支持 LTS)
java·spring·ai·solon·mcp·langchain4j
7澄12 小时前
深入解析 LeetCode 1572:矩阵对角线元素的和 —— 从问题本质到高效实现
java·算法·leetcode·矩阵·intellij-idea
诗9趁年华2 小时前
缓存三大问题深度解析:穿透、击穿与雪崩
java·spring·缓存
阳光明媚sunny2 小时前
分糖果算法题
java·算法