Android Studio加载SD卡中HTML文件的JavaScript函数失效求助
我帮你排查出了几个关键问题,咱们一步步调整就能解决:
1. JavaScript接口方法名不匹配
你HTML里的按钮点击事件调用的是AndroidFunction.openAndroidDialog(),但你的MyJavaScriptInterface类里定义的方法却是dialog()——名字对不上,WebView根本找不到对应的方法!
把Java里的方法名改成openAndroidDialog(),和HTML里的调用保持一致:
private class MyJavaScriptInterface{ Context mContext; MyJavaScriptInterface(Context c){ mContext = c; } @JavascriptInterface public void openAndroidDialog(){ // 这里修改方法名 AlertDialog.Builder myDialog = new AlertDialog.Builder(WriteWebPage.this); myDialog.setTitle("Danger!"); myDialog.setMessage("Hi"); myDialog.setPositiveButton("ON", null); myDialog.show(); } }
2. 初始化顺序错误导致空指针
在onCreate里,你先调用了wb.loadUrl("file://" + myExternalFile),但myExternalFile是在后面的isExternalStorageAvailable()判断里才初始化的,这时候myExternalFile还是null,直接加载会报错。
解决办法:把这行初始加载的代码注释掉,因为初始时文件还没创建,等点击按钮生成HTML后再加载就好。
3. 外部存储路径使用错误
getExternalFilesDir()的参数不能直接传"/sdcard/",这个方法需要传入特定的目录类型(比如Environment.DIRECTORY_DOCUMENTS)或者null(获取应用专属的外部文件目录)。用应用专属目录的好处是,Android 10及以上不需要申请额外的存储权限,也不会受分区存储的限制。
修改myExternalFile的初始化代码:
if(isExternalStorageAvailable()){ // 获取应用专属外部文件目录,无需额外权限 myExternalFile = new File(getExternalFilesDir(null), fileName); }
4. 调整WebView设置的顺序
建议把WebView的配置按合理顺序排列,先启用JavaScript,再添加接口,最后设置客户端:
@SuppressLint({"JavascriptInterface", "SetJavaScriptEnabled"}) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.read_webpage); btn = findViewById(R.id.btn); wb = findViewById(R.id.wb); final MyJavaScriptInterface myJavaScriptInterface = new MyJavaScriptInterface(this); // 先启用JavaScript wb.getSettings().setJavaScriptEnabled(true); // 再添加JS接口 wb.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction"); // 设置客户端 wb.setWebChromeClient(new WebChromeClient()); wb.setWebViewClient(new WebViewClient()); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { String a = "asd12sf"; String html = "<html><body>" + "<h3>Hello World</h3>" + "<p>" + a + "</p>" + "<input type='button' value='button' onClick='dialog()'/>" + "<script language='javascript'>" + "function dialog(){" + "AndroidFunction.openAndroidDialog();}" + "</script>" + "</body></html>"; FileOutputStream fos = new FileOutputStream(myExternalFile); fos.write(html.getBytes()); fos.close(); } catch (IOException e) { e.printStackTrace(); } wb.loadUrl("file://"+myExternalFile); } }); if(isExternalStorageAvailable()){ myExternalFile = new File(getExternalFilesDir(null), fileName); } }
做完这些调整后,你点击按钮生成HTML文件,WebView加载后点击页面上的按钮,应该就能正常弹出Android的对话框啦!
内容的提问来源于stack exchange,提问作者zam

