2012-02-15 100 views
13

我遇到了困扰了我好几天的问题。事实证明,这是一个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文件,使升级更容易。

回答

1

查询数据被附加到JavaScript文件(以及其他文件类型,如css),以防止浏览器缓存。查询数据对文件无用,但浏览器将其视为新的,因为位置发生了变化(在浏览器的眼中)并加载了新的副本。

我很高兴你找到了你的问题的答案,只是想我会给出我的意见,为什么人们使用这种方法。

+0

这里的问题不是浏览器缓存,但事实上,如果您附加查询数据,文件不会加载 – jtymann 2012-02-15 22:46:36

+0

了解。当我看到你的问题的这一部分时,只是想帮忙:“为什么有人会想这样做,因为文件显然无法对查询val做任何事情?” – 2012-02-17 03:06:03

2

感谢这篇文章,您告诉我最新的解决方案,它只是简单地使用IceCreamCordovaWebViewClient。

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