Android WebView空指针与本地HTML加载失败问题修复
Android WebView 问题修复方案
一、空指针异常(setBackgroundColor 调用在空对象上)
问题原因
recipe_description变量先调用方法,后执行findViewById初始化,此时变量为 nullsharedPref未初始化就调用getIsDarkTheme(),同样会触发空指针
修复步骤
- 先执行
findViewById(R.id.recipe_description)初始化 WebView 对象,再调用其配置方法 - 在使用
sharedPref前,添加初始化代码sharedPref = new SharedPref(this);
二、本地HTML文件无法加载(WebView无数据显示)
问题原因
代码中将 file:///android_asset/aboutcertified.html 作为字符串直接插入到 HTML 的 <body> 中,WebView 会把它当成纯文本显示,而非加载该文件的实际内容。
修复步骤
- 编写工具方法读取 assets 目录下的 HTML 文件内容
- 将读取到的 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
相关产品推荐
相关产品推荐

