2010-10-04 37 views
10

Tôi đang cố tải/tham chiếu hình ảnh từ thư mục nội dung của ứng dụng từ trong trang HTML trong WebView. Không giống như trong hầu hết các ví dụ, chính trang HTML không nằm trong thư mục nội dung nhưng được tải từ máy chủ qua http. Nền tảng của câu hỏi này là một số cải tiến hiệu suất giúp giảm thời gian tải (và lượng dữ liệu được truyền) bằng cách tải các hình ảnh tĩnh trực tiếp từ thiết bị. Tôi không chắc liệu Android có một số hạn chế ở đây hay không vì có khả năng nhất định khai thác ứng dụng bằng cách cho phép truy cập vào bộ nhớ tệp cục bộ từ một trang web được tải từ xa.Android: Cách tham chiếu hình ảnh nội dung từ trang html được tải từ xa trong chế độ xem web

Lần đầu tiên tôi cố gắng tải hình ảnh bằng cách sử dụng <img src="file:///android_asset/myimage.png"> nhưng điều này không thành công (vì lý do hiển nhiên). Nỗ lực tiếp theo của tôi là sử dụng một lớp học ContentProvider và các hình ảnh tham khảo bằng cách sử dụng <img src="content://com.myapp.assetcontentprovider/myimage.png">. ContentProvider này được thực hiện như sau:

public class AssetContentProvider extends ContentProvider 
{ 
private static final String URI_PREFIX = "content://com.myapp.assetcontentprovider"; 

public static String constructUri(String url) { 
    Uri uri = Uri.parse(url); 
    return uri.isAbsolute() ? url : URI_PREFIX + url; 
} 

@Override 
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 
    Log.d("AssetContentProvider", uri.getPath()); 
    try { 
     return getContext().getAssets().openFd(uri.getPath().substring(1)).getParcelFileDescriptor(); 
    } catch (IOException e) { 
     Log.d("AssetContentProvider", "IOException for " + uri.getPath()); 
     throw new FileNotFoundException(); 
    } 
} 

// more methods irrelevant for this post 
} 

Khi tải trang HTML tôi có thể nhìn thấy trong các bản ghi gỡ lỗi rằng openFile() là thực sự được kích hoạt từ WebView và nó trả về một đối tượng ParcelFileDescriptor hợp lệ nhưng vẫn là hình ảnh không được hiển thị. Không có thông báo lỗi nào được hiển thị trong nhật ký sẽ cho tôi biết rằng WebView đã từ chối tải/hiển thị hình ảnh. Bất kỳ ý tưởng nếu và làm thế nào điều này có thể làm việc?

+0

Bạn đã tìm thấy câu trả lời cho câu hỏi ban đầu của mình chưa (tại sao 'tệp: //' scheme ro 'content: //' one is not working right)? – Olegas

Trả lời

3

Đây là cách tôi làm trên phần java:

Chuỗi myHTML = "< img src = \" file: ///android_asset/myimage.jpg \ ""; myWebView.loadDataWithBaseURL ("tệp: /// android_asset /", myHTML, "văn bản/html", "UTF-8", "");

cổ vũ

+0

Cảm ơn câu trả lời của bạn nhưng đó không phải là giải pháp mà tôi đang tìm kiếm. Trong ứng dụng của tôi, trang HTML được tải từ một URL trên HTTP với myWebView.loadUrl() Hoặc bạn có đề xuất tải mã HTML bằng một cái gì đó như org.apache.http và sau đó đặt thủ công nó vào webview với loadDataWithBaseURL() không? – brotherli

+0

Bạn có thể làm điều đó. Nhưng phụ thuộc nếu HTML bạn đang tải xuống sử dụng liên kết tương đối hoặc tuyệt đối. Ah, hãy đảm bảo rằng nội dung của bạn được đặt tên theo đúng mẫu. (không có dấu cách và ký tự lạ ...) –

6

OK, nhờ câu trả lời của mufumbo Tôi đã tìm được cách làm việc để trộn nội dung cục bộ trong các trang HTML được tải từ xa. Các trang được tải bằng phương thức loadUrl() của WebView không tải hình ảnh được liên kết với tệp: /// android_asset/... Như một giải pháp thay thế, bạn có thể tìm nạp trang HTML bằng cách sử dụng org.apache.http.client.methods.HttpGet.HttpGet() và sau đó chuyển nó sang WebView với loadDataWithBaseURL(). Trong trường hợp này, WebView sẽ tải các tài nguyên được liên kết với tệp: /// android_asset/cũng như hình ảnh và tập lệnh qua HTTP. Dưới đây là mã xem web được tùy chỉnh của tôi:

public class CustomWebView extends WebView { 
    private String mURL; 

    public void loadUrlWithAssets(final String url) { 
     // copy url to member to allow inner classes accessing it 
     mURL = url; 

     new Thread(new Runnable() { 
      public void run() { 
       String html; 
       try { 
        html = NetUtil.httpGETResponse(mURL); 

        // replace some file paths in html with file:///android_asset/... 

        loadDataWithBaseURL(mURL, html, "text/html", "UTF-8", ""); 
       } 
       catch (IOException e) { 
        Log.e("CustomWebView.loadUrlWithAssets", "IOException", e); 
       } 
      } 
     }).start(); 
    } 
} 

Xin lưu ý rằng toàn bộ http tìm nạp được gói trong lớp tiện ích được trồng tại nhà NetUtil.

Với lớp này, có thể hiển thị các trang HTML từ máy chủ web và có một số tài nguyên tĩnh như hình ảnh hoặc bảng định kiểu được tải từ thư mục nội dung của ứng dụng để cải thiện tốc độ tải và tiết kiệm băng thông.

+0

Làm cách nào bạn quản lý để làm việc này cho các liên kết được nhấp trong chế độ xem web? Tôi chỉ hoạt động trên trang tải đầu tiên. – BradLaney

+0

@BradLaney @brotherli Tôi lấy lớp 'NetUtil' ở đâu – GameDevGuru

Các vấn đề liên quan