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

Android WebView获取部分网站(如Instagram)源码时应用崩溃的问题咨询

Android WebView获取部分网站(如Instagram)源码时应用崩溃的问题咨询

嘿,我仔细看了你的问题、代码和Logcat日志,马上就找到崩溃的原因了!

问题根源:TransactionTooLargeException

从Logcat里的错误信息可以看到:

android.os.TransactionTooLargeException: data parcel size 771000 bytes

Android的Binder事务有一个默认的大小限制(通常在1MB左右),当你通过Intent.putExtra传递大型网站(比如Instagram)的HTML源码时,数据量超过了这个限制,就会触发这个异常,导致应用崩溃。而像example.com这类小型网站的源码体积较小,刚好在限制范围内,所以不会出问题。

你的代码里就是直接把整个HTML源码通过Intent传递给SourceActivity,这在处理大型网站时肯定会出问题。

解决方案:避免用Intent传递大体积数据

我们可以改用两种更安全的方式来传递或存储大体积的源码:

方案1:通过自定义Application类共享数据

这种方式适合中等大小的源码,操作简单:

  1. 首先创建一个自定义的Application类:
package com.example.pokuswebview2;

import android.app.Application;

public class MyApp extends Application {
    private String pageSource;

    public String getPageSource() {
        return pageSource;
    }

    public void setPageSource(String pageSource) {
        this.pageSource = pageSource;
    }
}
  1. 在AndroidManifest.xml里注册这个Application:
<application
    android:name=".MyApp"
    <!-- 其他原有配置 -->
    >
    <!-- 原有Activity配置 -->
</application>
  1. 修改MainActivity的点击事件逻辑,把源码存入Application:
btnShowSource.setOnClickListener(v -> {
    webView.evaluateJavascript("(function() { return document.documentElement.outerHTML; })()", html -> {
        if (html != null) {
            // 将源码存入自定义Application
            ((MyApp) getApplication()).setPageSource(html);
            Intent intent = new Intent(MainActivity.this, SourceActivity.class);
            startActivity(intent);
        } else {
            Toast.makeText(MainActivity.this, "Chyba při získávání zdrojového kódu", Toast.LENGTH_SHORT).show();
        }
    });
});
  1. 修改SourceActivity从Application读取源码:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_source);

    tvSourceCode = findViewById(R.id.tvSourceCode);

    // 从自定义Application获取源码
    String pageSource = ((MyApp) getApplication()).getPageSource();

    if (pageSource != null) {
        tvSourceCode.setText(pageSource);
        // 用完后清空,避免占用内存
        ((MyApp) getApplication()).setPageSource(null);
    }
}

方案2:写入本地临时文件

如果网站源码特别庞大(比如超过几MB),用Application可能会占用过多内存,这时候可以写入本地缓存文件:

  1. 修改MainActivity的点击事件,把源码写入临时文件:
btnShowSource.setOnClickListener(v -> {
    webView.evaluateJavascript("(function() { return document.documentElement.outerHTML; })()", html -> {
        if (html != null) {
            try {
                // 在缓存目录创建临时文件
                File tempFile = File.createTempFile("page_source", ".html", getCacheDir());
                FileWriter writer = new FileWriter(tempFile);
                writer.write(html);
                writer.close();
                
                // 传递临时文件路径给SourceActivity
                Intent intent = new Intent(MainActivity.this, SourceActivity.class);
                intent.putExtra("SOURCE_FILE_PATH", tempFile.getAbsolutePath());
                startActivity(intent);
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(MainActivity.this, "Chyba při ukládání zdrojového kódu", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(MainActivity.this, "Chyba při získávání zdrojového kódu", Toast.LENGTH_SHORT).show();
        }
    });
});
  1. 修改SourceActivity读取临时文件并显示:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_source);

    tvSourceCode = findViewById(R.id.tvSourceCode);

    String filePath = getIntent().getStringExtra("SOURCE_FILE_PATH");
    if (filePath != null) {
        try {
            File file = new File(filePath);
            BufferedReader reader = new BufferedReader(new FileReader(file));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            reader.close();
            tvSourceCode.setText(sb.toString());
            
            // 读取完成后删除临时文件,避免占用存储空间
            file.delete();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(this, "Chyba při čtení zdrojového kódu", Toast.LENGTH_SHORT).show();
        }
    }
}

额外注意事项

  • 转义字符处理:evaluateJavascript返回的HTML字符串会被转义(比如包含\"这类转义符),如果想要更清晰的源码显示,可以额外做转义还原处理,比如用html = html.replace("\\", "").substring(1, html.length() - 1);来去掉前后的引号和多余转义。
  • 内存管理:大型网站的源码体积很大,用完后记得及时清空或删除,避免内存泄漏或存储空间占用。

备注:内容来源于stack exchange,提问作者Mirek6

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 11:53:00