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

Android WebView空指针与本地HTML加载失败问题修复

Android WebView 问题修复方案

一、空指针异常(setBackgroundColor 调用在空对象上)

问题原因

  1. recipe_description 变量先调用方法,后执行 findViewById 初始化,此时变量为 null
  2. sharedPref 未初始化就调用 getIsDarkTheme(),同样会触发空指针

修复步骤

  • 先执行 findViewById(R.id.recipe_description) 初始化 WebView 对象,再调用其配置方法
  • 在使用 sharedPref 前,添加初始化代码 sharedPref = new SharedPref(this);

二、本地HTML文件无法加载(WebView无数据显示)

问题原因

代码中将 file:///android_asset/aboutcertified.html 作为字符串直接插入到 HTML 的 <body> 中,WebView 会把它当成纯文本显示,而非加载该文件的实际内容。

修复步骤

  1. 编写工具方法读取 assets 目录下的 HTML 文件内容
  2. 将读取到的 HTML 内容与样式代码拼接,再传入 loadDataWithBaseURL 加载

修正后的完整代码

public class ActivityRecipeDaily extends AppCompatActivity {
    private WebView recipe_description;
    SharedPref sharedPref;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Tools.getTheme(this);
        setContentView(R.layout.activity_recipe_detail2);
        Tools.getLayoutDirections(this, RTL_MODE);

        // 先初始化sharedPref和WebView,避免空指针
        sharedPref = new SharedPref(this);
        recipe_description = findViewById(R.id.recipe_description);

        // 初始化WebView配置
        recipe_description.setBackgroundColor(Color.TRANSPARENT);
        recipe_description.setFocusableInTouchMode(false);
        recipe_description.setFocusable(false);
        WebSettings webSettings = recipe_description.getSettings();
        webSettings.setDefaultTextEncodingName("UTF-8");
        
        Resources res = getResources();
        int fontSize = res.getInteger(R.integer.font_size);
        webSettings.setDefaultFontSize(fontSize);

        String mimeType = "text/html; charset=UTF-8";
        String encoding = "utf-8";
        
        // 读取assets中的HTML文件内容
        String htmlContent = readAssetFile("aboutcertified.html");

        String bg_paragraph;
        if (sharedPref.getIsDarkTheme()) {
            bg_paragraph = "<style type=\"text/css\">body{color: #eeeeee;}";
        } else {
            bg_paragraph = "<style type=\"text/css\">body{color: #000000;}";
        }

        String font_style_default = "<style type=\"text/css\">@font-face {font-family: MyFont;src: url(\"file:///android_asset/font/custom_font.ttf\")}body {font-family: MyFont; font-size: medium; text-align: left;}</style>";

        String text = "<html><head>"
                + font_style_default
                + "<style>img{max-width:100%;height:auto;} figure{max-width:100%;height:auto;} iframe{width:100%;}</style> "
                + bg_paragraph
                + "</style></head>"
                + "<body>"
                + htmlContent
                + "</body></html>";

        String text_rtl = "<html dir='rtl'><head>"
                + font_style_default
                + "<style>img{max-width:100%;height:auto;} figure{max-width:100%;height:auto;} iframe{width:100%;}</style> "
                + bg_paragraph
                + "</style></head>"
                + "<body>"
                + htmlContent
                + "</body></html>";

        if (RTL_MODE) {
            recipe_description.loadDataWithBaseURL("file:///android_asset/", text_rtl, mimeType, encoding, null);
        } else {
            recipe_description.loadDataWithBaseURL("file:///android_asset/", text, mimeType, encoding, null);
        }
    }

    // 工具方法:读取assets目录下的文件内容
    private String readAssetFile(String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            InputStream inputStream = getAssets().open(fileName);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }
            bufferedReader.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }
}

额外说明

  • 读取 assets 文件时需捕获 IOException,避免因文件不存在或读取失败导致崩溃
  • loadDataWithBaseURL 的第一个参数设为 "file:///android_asset/",可确保 HTML 中引用的本地资源(如自定义字体)能正确加载

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:20:40