2012-02-15 27 views
13

Tôi gặp phải sự cố đã khiến tôi thất vọng trong nhiều ngày. Hóa ra đó là một trục trặc Android và đã được gửi đi, xác nhận, và hy vọng sẽ được sửa trong một bản phát hành trong tương lai. Bây giờ tôi đã tìm thấy một giải pháp mà làm việc cho tôi, và sẽ cung cấp cho nó dưới đây, tuy nhiên giải pháp không phải là hoàn hảo vì nó liên quan đến việc chỉnh sửa nguồn khoảng cách điện thoại. Chủ yếu là câu hỏi của tôi là nếu ai đó có thể tìm ra giải pháp tốt hơn cho vấn đề này.Sự cố khi tải các tệp javascript cục bộ bên trong một chế độ xem web

Lỗi:
Có sự cố khi bạn cố gắng tải trang bên trong một WebView trên Android 3.0+. Trục trặc là nếu trang đó tham chiếu bất kỳ tệp javascript cục bộ nào, bạn không thể nối thêm dữ liệu truy vấn vào url. Về cơ bản

này hoạt động:
<script type="text/javascript" src="StaticJS.js"></script>

này không hoạt động:
<script type="text/javascript" src="StaticJS.js?var=val"></script>

Tại sao các địa ngục bất cứ ai muốn làm điều này kể từ khi tập tin rõ ràng là không thể làm bất cứ điều gì với Vals truy vấn? Đối với tôi, tôi có một ứng dụng phonegap tải một tập tin cài đặt qua JSONP, tuy nhiên nếu một tập tin cài đặt không được chỉ định, nó mặc định là một tập tin cục bộ. Vì vậy, yeah, các tập tin không thể xử lý dữ liệu truy vấn nhưng nó sẽ được tốt đẹp để sử dụng cùng một định dạng tập tin và tải cấu trúc.


Giải pháp 1 (Non-PhoneGap)

Vì vậy, có một giải pháp dễ dàng để này nếu mục tiêu nền tảng Android là 11 (Honeycomb) hoặc cao hơn. (Miễn là bạn cẩn thận và không sử dụng bất kỳ phương pháp nào không tồn tại ở bất kỳ cấp API nào thấp hơn, mã này sẽ chạy trên < 11 apis, nhưng bạn vẫn phải đặt 11 làm mục tiêu của mình)

Về cơ bản bạn thêm một WebViewClient cho WebView sử dụng phương thức shouldInterceptRequest để chặn việc tải các tệp js cục bộ với dữ liệu truy vấn được đính kèm.

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; 
     } 
    } 

} 

Để đặt WebViewClient, mã của bạn sẽ giống như thế này:

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"); 
    } 
} 

Giải pháp 2 (PhoneGap)

Bây giờ cho PhoneGap Tôi không có một giải pháp làm sạch . Giải pháp của tôi là để đi và tải về mã nguồn PhoneGap và chỉnh sửa CordovaWebViewClient bằng cách thêm các phương pháp sau đây:

@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; 
    } 
} 

Giải pháp 3 (không tồn tại)

Giải pháp này sẽ hy vọng có một số dễ dàng để bao gồm lớp hoặc tinh chỉnh cho hoạt động chính để bạn có thể sử dụng khoảng cách điện thoại nhưng chỉ có thể sử dụng tệp .jar của mã, giúp nâng cấp dễ dàng hơn.

Trả lời

1

Dữ liệu truy vấn được thêm vào tệp javascript (và các loại tệp khác như css) để ngăn bộ nhớ đệm của trình duyệt. Dữ liệu truy vấn là vô ích đối với tệp nhưng trình duyệt xử lý tệp đó là mới vì vị trí được thay đổi (trong con mắt của trình duyệt) và nó tải một bản sao mới.

Tôi rất vui vì bạn đã tìm thấy câu trả lời cho vấn đề của mình, chỉ nghĩ rằng tôi sẽ đưa ra ý kiến ​​của mình về lý do mọi người sử dụng phương pháp này.

+0

Vấn đề ở đây không phải là bộ nhớ cache của trình duyệt, nhưng thực tế các tệp không tải nếu bạn nối dữ liệu truy vấn – jtymann

+0

Đã hiểu. Chỉ muốn giúp đỡ khi tôi thấy phần này của câu hỏi của bạn: "Tại sao mọi người lại muốn làm điều này vì tập tin rõ ràng không thể làm gì với các câu hỏi truy vấn?" –

2

Cảm ơn bài đăng này, bạn đã đưa tôi vào giải pháp mới nhất chỉ đơn giản là sử dụng IceCreamCordovaWebViewClient.

@Override 
    public void init() { 
    super.init(webView, new IceCreamCordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView)); 
} 
Các vấn đề liên quan