在webview中加载本地JavaScript文件的问题
我遇到了困扰了我好几天的问题。事实证明,这是一个Android小故障,并已提交,确认,并希望将在未来的版本中修复。现在我找到了适合我的解决方案,并将在下面提供它,但解决方案并不完美,因为它涉及编辑手机间隙源。主要是我的问题是,如果有人能找到更好的解决这个问题。在webview中加载本地JavaScript文件的问题
错误:
当您尝试在Android 3.0+的WebView内部加载页面时会出现一个小故障。毛病是,如果该页面引用任何本地JavaScript文件,你不能追加查询数据到网址。基本上
这工作:<script type="text/javascript" src="StaticJS.js"></script>
这不起作用:<script type="text/javascript" src="StaticJS.js?var=val"></script>
究竟为什么会有人想这样做,因为该文件显然不能做与查询瓦尔斯什么?对我来说,我有一个phonegap应用程序,通过JSONP加载设置文件,但是如果未指定设置文件,它将默认为本地文件。所以,文件无法处理查询数据,但使用相同的文件格式和加载结构会很好。
溶液1(非PhoneGap的)
因此,有一个简单的解决方案,这一点,如果所述目标机器人平台是11(蜂窝)或更高。 (只要您非常小心,并且不使用任何API级别不存在的方法,此代码将在apis上运行,但您仍然必须将11设置为目标)
基本上,您添加WebView的WebViewClient利用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文件,使升级更容易。
查询数据被附加到JavaScript文件(以及其他文件类型,如css),以防止浏览器缓存。查询数据对文件无用,但浏览器将其视为新的,因为位置发生了变化(在浏览器的眼中)并加载了新的副本。
我很高兴你找到了你的问题的答案,只是想我会给出我的意见,为什么人们使用这种方法。
感谢这篇文章,您告诉我最新的解决方案,它只是简单地使用IceCreamCordovaWebViewClient。
@Override
public void init() {
super.init(webView, new IceCreamCordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView));
}
这里的问题不是浏览器缓存,但事实上,如果您附加查询数据,文件不会加载 – jtymann 2012-02-15 22:46:36
了解。当我看到你的问题的这一部分时,只是想帮忙:“为什么有人会想这样做,因为文件显然无法对查询val做任何事情?” – 2012-02-17 03:06:03