Adnroid WebView从http协议加载本地html,而不是file协议

1.使用WebViewAssetLoader 需要在build.gradle中添加webkit
implementation 'androidx.webkit:webkit:1.6.0'

2.然后设置Webview
 protected void webviewSet() {
        WebView wv = binding.wv;
        WebSettings wvSettings = wv.getSettings();
        final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
                .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this.getContext()))
                .build();
        wvSettings.setJavaScriptEnabled(true);
        wvSettings.setAllowFileAccessFromFileURLs(false);
        wvSettings.setAllowUniversalAccessFromFileURLs(false);
        wvSettings.setAllowFileAccess(true);
        wvSettings.setAllowContentAccess(true);
        wvSettings.setDomStorageEnabled(true);

        wv.setWebViewClient(new WebViewClientCompat() {
            @Override
            @RequiresApi(21)
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                WebResourceResponse interceptedWebRequest = assetLoader.shouldInterceptRequest(request.getUrl());
                if (interceptedWebRequest != null) {
            // 在旧版本Android中会出现以下错误
            // Failed to load module script: The server responded with a non-JavaScript MIME type of "". 
            // 这里手动设置mime类型
if (request.getUrl().toString().endsWith(".js")) { interceptedWebRequest.setMimeType("text/javascript"); } } return interceptedWebRequest; } @Override @SuppressWarnings("deprecation") // for API < 21 public WebResourceResponse shouldInterceptRequest(WebView view, String url) { WebResourceResponse interceptedWebRequest = assetLoader.shouldInterceptRequest(Uri.parse(url)); if (interceptedWebRequest != null) { if (Uri.parse(url).toString().endsWith(".js")) { interceptedWebRequest.setMimeType("text/javascript"); } } return interceptedWebRequest; } }); // 暴露object对象暴露给Js, addJavascriptInterface,让js能够调用java对象的方法 AndroidForJS sdk = new AndroidForJS(this); wv.addJavascriptInterface(sdk, "android"); // Assets are hosted under http(s)://appassets.androidplatform.net/assets/... . // If the application's assets are in the "main/assets" folder this will read the file // from "main/assets/www/index.html" and load it as if it were hosted on: // https://appassets.androidplatform.net/assets/www/index.html
     // 本地的html文件存放在main/assets/index.html, 默认通过以下链接加载 wv.loadUrl("https://appassets.androidplatform.net/assets/index.html");
     // wv.loadUrl("file:///android_asset/index.html");
     // wv.loadUrl("http://www.baidu.com"); // 监听返回键,跳转回上一个url而不是关闭整个页面 wv.setOnKeyListener((view, i, event) -> { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (i == KeyEvent.KEYCODE_BACK && wv.canGoBack()) {// mWebView.goBack(); wv.loadUrl("javascript:window.history.back(-1)"); return true; } } return false; }); }

 

3. 如果使用了vite,那么vite配置也可以更改以下

vite.config.ts文件

 1 export default defineConfig({
 2   // base: '/android_asset/',   // 用file协议加载,那么构建的url加上可以加上这个
 3   base: './',            // http协议加载,设置./
 4   plugins: [
 5     vue(),
 6     vueJsx(),
 7   ],
 8   resolve: {
 9     alias: {
10       '@': fileURLToPath(new URL('./src', import.meta.url))
11     }
12   },
13   build: {
14     outDir: '../assets/',   // 导出目录
15     emptyOutDir: true,
16     target: ['es2015', 'chrome58']    // 如果需要运行在比较旧的Webview上
17   }
18 })        

 


javascript - 在 Android 的 WebView 中放宽 MIME 类型检查?或者强制常规javascript的模块类型? - IT工具网 (coder.work)
posted @ 2024-01-19 15:51  umbed  阅读(29)  评论(0编辑  收藏  举报