2012-02-15 23 views
13

私は何日間も私を悩ませていました。 Androidの不具合であり、提出され、確認され、今後のリリースで修正されることが期待されています。今私は私のために働く解決策を見つけて、それを下に提供しますが、解決策は完全なものではありません。主に私の質問は、誰かがこの問題のより良い解決策を見つけることができる場合です。webview内でローカルjavascriptファイルをロードする際の問題

バグ:
Android 3.0以降でWebView内のページを読み込もうとするとグリッチが発生します。欠点は、そのページがローカルのjavascriptファイルを参照する場合、URLにクエリデータを追加できないということです。基本的には

これは動作します:
<script type="text/javascript" src="StaticJS.js"></script>

これは動作しません:
<script type="text/javascript" src="StaticJS.js?var=val"></script>

明らかにファイルがクエリヴァルスと何もできないので、地獄がこれを行うには誰もがしたいと思うのはなぜ?まあ私の場合、JSONP経由で設定ファイルを読み込むphonegapアプリケーションがありますが、設定ファイルが指定されていない場合は、デフォルトでローカルファイルになります。だから、ファイルがクエリデータを処理することはできませんが、同じファイル形式と読み込み構造を使用するといいでしょう。


溶液1(非PhoneGapの)

ターゲットAndroidプラットフォーム11(ハニカム)以上であればこれに対する簡単な解決策があります。 (あなたが慎重で、より低いAPIレベルに存在しないメソッドを使用しない限り、このコードは< 11 apisで実行されますが、まだあなたのターゲットとして11を設定する必要があります)

基本的にshouldInterceptRequestメソッドを使用してローカルjsファイルの読み込みをアタッチしてクエリデータを添付したWebViewへのWebViewClient。

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のために、私はきれいな解決策を持っていません。うまくいけば含めていくつかの簡単だろう。このソリューション

@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(実在しない)

:私のソリューションは行くとダウンロードPhoneGapのソースを、以下の方法を追加してCordovaWebViewClientを編集することですクラスを調整するか、主なアクティビティを微調整して電話のギャップを使用することができますが、コードの.jarファイルを使用するだけでアップグレードが容易になります。

答えて

1

ブラウザのキャッシュを防止するために、クエリデータがjavascriptファイル(およびcssなどの他のファイルタイプ)に追加されます。クエリデータはファイルにとって無用ですが、ブラウザが新しいものとして扱うのは、場所が(ブラウザの目で)変更され、新しいコピーがロードされるためです。

私はあなたの問題に対する答えを見つけられたことをうれしく思っています。人々がこの方法を使用する理由についての私の意見を伝えたいと思っています。

+0

ここでの問題はブラウザのキャッシュではなく、クエリデータを追加するとファイルが読み込まれないということです。 – jtymann

+0

ちょうど私があなたの質問のこの部分を見たときに助けたかったのです。「なぜファイルがクエリの値で何もできないので、なぜこれをやりたいのですか? –

2

この投稿をお寄せいただきありがとうございます。私はIceCreamCordovaWebViewClientを使用するだけの最新のソリューションに私を結びつけました。

@Override 
    public void init() { 
    super.init(webView, new IceCreamCordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView)); 
} 
関連する問題