Веб-просмотр Android: Внесите локальный файл Javascript на удаленную веб-страницу

Его спрашивали много раз раньше, я просматривал все, пока не было четких ответов.

Вопрос упрощен: можно ли добавить локальный файл Javascript (из актива или хранилища) на удаленную веб-страницу, загруженную в веб-представление Android? Я знаю, что такие файлы можно вводить на локальные веб-страницы (Атрибуты HTML), загружаемые в веб-представление.

Зачем мне это нужно? : Чтобы сделать просмотр более быстрым, избегая загрузки больших файлов, таких как Js и CSS-файлы каждый раз. Я хочу избежать кэширования веб-представления.

Solutions Collecting From Web of "Веб-просмотр Android: Внесите локальный файл Javascript на удаленную веб-страницу"

Существует способ «принудительно» ввести ваши локальные файлы Javascript из локальных активов (например, assets / js / script.js) и обойти «Не разрешено загружать локальный ресурс: file: /// android_assets / js /script.js … ".

Это похоже на то, что описано в другом потоке ( Android-просмотр Android, загрузка файла javascript в папке с ресурсами ), с дополнительным кодированием / декодированием BASE64 для представления вашего файла Javascript в виде строки для печати.

Я использую Android 4.4.2, API уровня 19 Virtual Device.

Вот некоторые фрагменты кода:

[активы / JS / script.js]:

'use strict'; function test() { // ... do something } // more Javascript 

[MainActivity.java]:

  ... WebView myWebView = (WebView) findViewById(R.id.webView); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setAllowUniversalAccessFromFileURLs(true); myWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return false; } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); injectScriptFile(view, "js/script.js"); // see below ... // test if the script was loaded view.loadUrl("javascript:setTimeout(test(), 500)"); } private void injectScriptFile(WebView view, String scriptFile) { InputStream input; try { input = getAssets().open(scriptFile); byte[] buffer = new byte[input.available()]; input.read(buffer); input.close(); // String-ify the script byte-array using BASE64 encoding !!! String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP); view.loadUrl("javascript:(function() {" + "var parent = document.getElementsByTagName('head').item(0);" + "var script = document.createElement('script');" + "script.type = 'text/javascript';" + // Tell the browser to BASE64-decode the string into your script !!! "script.innerHTML = window.atob('" + encoded + "');" + "parent.appendChild(script)" + "})()"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); myWebView.loadUrl("http://www.example.com"); ... 

Да, вы можете использовать shouldInterceptRequest (), чтобы перехватить удаленный URL-адрес и вернуть локально сохраненный контент.

 WebView webview = (WebView) findViewById(R.id.webview); webview.setWebViewClient(new WebViewClient() { @Override public WebResourceResponse shouldInterceptRequest (final WebView view, String url) { if (url.equals("script_url_to_load_local")) { return new WebResourceResponse("text/javascript", "UTF-8", new FileInputStream("local_url"))); } else { return super.shouldInterceptRequest(view, url); } } }); 

LoadUrl будет работать только в старой версии. UseJavascript

 webview.evaluateJavascript("(function() { document.getElementsByName('username')[0].value='USERNAME';document.getElementsByName('password')[0].value='PASSWORD'; "+ "return { var1: \"variable1\", var2: \"variable2\" }; })();", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); // Prints: {"var1":"variable1","var2":"variable2"} } });