Проблема с загрузкой локальных файлов javascript внутри webview

У меня был вопрос, который мучил меня в течение нескольких дней. Оказалось, что это был глюк Android, и он был представлен, подтвержден и, надеюсь, будет исправлен в будущем выпуске. Теперь я нашел решение, которое работает для меня, и предоставит его ниже, однако решение не является совершенным, поскольку оно включает в себя редактирование источника разрыва телефона. В основном, мой вопрос в том, может ли кто-то найти лучшее решение этой проблемы.

Баг:
При попытке загрузить страницу внутри WebView на Android 3.0+ произошел сбой. Сбой заключается в том, что если эта страница ссылается на любые локальные файлы javascript, вы не можете добавлять данные запроса к URL-адресу. В основном

Это работает:
<script type="text/javascript" src="StaticJS.js"></script>

Это не работает:
<script type="text/javascript" src="StaticJS.js?var=val"></script>

Почему, черт возьми, кто-нибудь захочет это сделать, поскольку файл явно ничего не может сделать с помощью запросов vals? Ну, для меня у меня есть приложение для телефонных разговоров, которое загружает файл настроек через JSONP, однако если файл настроек не указан, он по умолчанию использует локальный файл. Так что да, файл не может обрабатывать данные запроса, но было бы неплохо использовать тот же формат файла и структуру загрузки.


Решение 1 (Non-PhoneGap)

Таким образом, это простое решение, если целевая платформа Android составляет 11 (Honeycomb) или выше. (Пока вы будете осторожны и не используете какой-либо метод, который не существует на каких-либо более низких уровнях API, этот код будет работать на <11 apis, но вам все равно придется установить 11 в качестве вашей цели)

В основном вы добавляете WebViewClient в WebView, который использует метод shouldInterceptRequest для перехвата загрузки локальных файлов js с прикрепленными данными запроса.

 import java.io.IOException; import java.io.InputStream; import android.content.res.AssetManager; import android.webkit.WebResourceResponse; import android.webkit.WebView; import android.webkit.WebViewClient; public class PatchingWebViewClient extends WebViewClient{ AssetManager am; public PatchingWebViewClient(AssetManager am){ this.am = am; } @Override public WebResourceResponse shouldInterceptRequest (WebView view, String url){ if(url.indexOf("file:///android_asset") == 0 && url.contains("?")){ String filePath = url.substring(22, url.length()); filePath = filePath.substring(0, filePath.indexOf("?")); try { InputStream is = am.open(filePath); WebResourceResponse wr = new WebResourceResponse("text/javascript", "UTF-8", is); return wr; } catch (IOException e) { return null; } }else{ return null; } } } 

Чтобы установить WebViewClient, ваш код будет выглядеть примерно так:

 import android.app.Activity; import android.os.Bundle; import android.webkit.WebView; public class CanWeBreakAWebViewActivity extends Activity { WebView mWebView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.webview); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.setWebViewClient(new PatchingWebViewClient(this.getAssets())); mWebView.loadUrl("file:///android_asset/index.html"); } } 

Решение 2 (PhoneGap)

Теперь для Phonegap у меня нет чистого решения. Мое решение – пойти и загрузить источник Phonegap и отредактировать файл CordovaWebViewClient, добавив следующий метод:

 @Override public WebResourceResponse shouldInterceptRequest (WebView view, String url){ if(url.indexOf("file:///android_asset") == 0 && url.contains("?")){ String filePath = url.substring(22, url.length()); filePath = filePath.substring(0, filePath.indexOf("?")); try { InputStream is = ctx.getAssets().open(filePath); WebResourceResponse wr = new WebResourceResponse("text/javascript", "Cp1252", is); return wr; } catch (IOException e) { return null; } }else{ return null; } } 

Решение 3 (несуществующее)

Это решение, мы надеемся, будет легко включать класс или настройку в основное действие, чтобы вы могли использовать разницу в телефоне, но могли бы просто использовать .jar-файл кода, упростив обновление.

Solutions Collecting From Web of "Проблема с загрузкой локальных файлов javascript внутри webview"

Спасибо за этот пост, вы указали мне на последнее решение, которое просто использует IceCreamCordovaWebViewClient.

 @Override public void init() { super.init(webView, new IceCreamCordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView)); } 

Данные запроса добавляются в файлы javascript (и другие типы файлов, такие как css), чтобы предотвратить кеширование браузера. Данные запроса бесполезны для файла, но браузер рассматривает его как новый, поскольку местоположение изменяется (в глазах браузера) и загружает новую копию.

Я рад, что вы нашли ответ на свою проблему, просто подумал, что я расскажу о том, почему люди используют этот метод.