2012-02-15 5 views
13

며칠 동안 저를 괴롭혔던 문제가있었습니다. 그것은 그것이 안드로이드 결함이었고, 제출되었고, 확인되었고, 미래의 릴리스에서 잘하면 수정 될 것이라고 밝혀졌습니다. 이제는 나를 위해 작동하는 솔루션을 찾았지만 아래에서 설명 하겠지만 솔루션은 전화 갭 소스 편집과 관련하여 완벽하지 않습니다. 주로 내 질문은 누군가가이 문제에 대한 더 나은 해결책을 찾을 수 있는지 여부입니다.webview에서 로컬 javascript 파일을로드하는 데 문제가 있습니다.

버그 :
Android 3.0 이상에서 WebView 내부 페이지를로드하려고하면 결함이 있습니다. 결함은 해당 페이지가 모든 로컬 자바 스크립트 파일을 참조하면 URL에 쿼리 데이터를 추가 할 수 없다는 것입니다. 기본적으로

이 작동 :
<script type="text/javascript" src="StaticJS.js"></script>

이 작동하지 않습니다 :
<script type="text/javascript" src="StaticJS.js?var=val"></script>

이유는 도대체 누구 쿼리 발스와 아무것도 할 수 없습니다 분명히 파일 때문에이 작업을 수행 할 것인가? 나에게는 JSONP를 통해 설정 파일을로드하는 phonegap 응용 프로그램이 있지만 설정 파일을 지정하지 않으면 기본값이 로컬 파일로 설정됩니다. 그래, 파일은 쿼리 데이터를 처리 할 수 ​​없지만 동일한 파일 형식과로드 구조를 사용하는 것이 좋습니다. 타겟 로이드 플랫폼 (11) (벌집) 또는 높은 경우


용액 1 (비 폰갭)의

따라서이 용액에 쉽게있다. (조심하고 더 낮은 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 (폰갭)를

을 지금 폰갭 내가 깨끗한 솔루션이없는 .

@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이 솔루션은 희망 약간 쉬운 것입니다

(존재하지 않는 비)를 포함하는 : 내 솔루션 가서 폰갭 소스를 다운로드하고 다음과 같은 방법을 추가하여 CordovaWebViewClient을 편집하는 것입니다 클래스를 조정하거나 주요 활동을 조정하여 전화 간격을 사용할 수 있지만 코드의 .jar 파일 만 사용할 수 있으므로 업그레이드가 쉬워집니다.

답변

1

브라우저 캐싱을 방지하기 위해 쿼리 데이터가 javascript 파일 (및 CSS와 같은 다른 파일 형식)에 추가됩니다. 쿼리 데이터는 파일에는 쓸모가 없지만 브라우저의 위치에서 위치가 변경되고 새로운 복사본이로드되기 때문에 브라우저는 파일을 새로운 것으로 간주합니다.

귀하의 문제에 대한 답을 찾았 기 때문에 기쁩니다. 사람들이이 방법을 사용하는 이유에 대한 의견을 드리고 싶습니다.

+0

여기서 문제는 브라우저 캐싱,하지만 이해 쿼리 데이터 – jtymann

+0

를 추가하면 파일이로드되지 않는다는 사실이 아니다. 이 질문을 보았을 때 도움을주고 싶었습니다. "왜 파일이 ​​쿼리 VAL에 아무 것도 할 수 없기 때문에 왜이 일을 원했을까요?" –

2

이 게시물을 보내 주셔서 감사합니다. IceCreamCordovaWebViewClient를 사용하는 최신 솔루션으로 안내해 드렸습니다.

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