2010-10-04 4 views
10

Я пытаюсь загрузить/ссылаться на изображения из папки ресурсов приложения из HTML-страницы в WebView. В отличие от большинства примеров, сама страница HTML не находится в папке с ресурсами, но загружается с сервера через http. Основой этого вопроса являются некоторые улучшения производительности, которые должны сократить время загрузки (и количество переданных данных) путем загрузки статических изображений непосредственно с устройства. Я не уверен, что у Android есть некоторые ограничения здесь, потому что есть определенная возможность использовать приложение, разрешая доступ к локальному хранилищу файлов с удаленной загруженной веб-страницы.Android: Как ссылаться на изображения объектов с удаленно загруженной страницы html в webview

Сначала я попытался загрузить изображения, используя <img src="file:///android_asset/myimage.png">, но это не удалось (по понятным причинам). Моя следующая попытка состояла в том, чтобы использовать класс ContentProvider и контрольные изображения, используя <img src="content://com.myapp.assetcontentprovider/myimage.png">. Это ContentProvider реализуется следующим образом:

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 
} 

При загрузке страницы HTML можно увидеть в журнале отладки, что openFile() фактически срабатывает от WebView и возвращает действительный ParcelFileDescriptor объект, но по-прежнему не отображается изображение. В журнале нет сообщений об ошибках, которые скажут мне, что WebView отказался загружать/отображать изображение. Любые идеи, если и как это могло бы работать?

+0

Вы нашли ответ на свой первоначальный вопрос (почему? File: // 'schem ro' content: // 'one is not working right)? – Olegas

ответ

3

Это, как я на Java части:

Струнный myHTML = "< IMG SRC = \" Файл: ///android_asset/myimage.jpg \ ""; myWebView.loadDataWithBaseURL ("file: /// android_asset /", myHTML, "text/html", "UTF-8", "");

веселит

+0

Спасибо за ваш ответ, но это не совсем то решение, которое я искал. В моем приложении HTML-страница загружается с URL-адреса через HTTP с помощью myWebView.loadUrl(). Или вы предлагаете загрузить код HTML с чем-то вроде org.apache.http, а затем вручную поместить его в webview с помощью loadDataWithBaseURL()? – brotherli

+0

Вы могли бы это сделать. Но зависит от того, использует ли HTML, который вы загружаете, относительные или абсолютные ссылки. Ах, убедитесь, что ваши активы названы в надлежащей форме. (без пробелов и странных символов ...) –

6

OK, благодаря ответу mufumbo, я нашел в настоящее время рабочего хак смешивать местные активы удалены загружаемых HTML-страницы. Страницы, загруженные с использованием метода WebView loadUrl(), не загружают изображения, связанные с файлом: /// android_asset/... В качестве обходного пути вы можете получить HTML-страницу с помощью org.apache.http.client.methods.HttpGet.HttpGet(), а затем передать ее в WebView с помощью loadDataWithBaseURL(). В этом случае WebView будет загружать ресурсы, связанные с файлом: /// android_asset /, а также изображения и скрипты через HTTP. Вот мой пользовательский код WebView:

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

Пожалуйста, обратите внимание, что весь HTTP выборка заворачивают в доморощенной полезности класса NetUtil.

С помощью этого класса можно отображать HTML-страницы с веб-сервера и иметь некоторые статические ресурсы, такие как изображения или таблицы стилей, загруженные из папки ресурсов приложения, чтобы повысить скорость загрузки и сэкономить пропускную способность.

+0

Как вам удалось заставить это работать на ссылки, которые нажали в веб-виде? Шахта работает только при загрузке первой страницы. – BradLaney

+0

@BradLaney @brotherli Где я могу получить класс NetUtil? – GameDevGuru