2010-10-04 5 views
10

Ich versuche verweisen zu laden/Referenzbilder aus dem Vermögen Ordner App innerhalb einer HTML-Seite in einem WebView. Anders als in den meisten Beispielen befindet sich die HTML-Seite selbst nicht im Ordner Assets, sondern wird von einem Server über http geladen. Der Hintergrund dieser Frage sind einige Leistungsverbesserungen, die die Ladezeit (und die Menge der übertragenen Daten) reduzieren sollten, indem statische Bilder direkt vom Gerät geladen werden. Ich bin mir nicht sicher, ob Android hier einige Einschränkungen hat, da es eine gewisse Möglichkeit gibt, die App auszunutzen, indem man von einer entfernt geladenen Webseite auf den lokalen Dateispeicher zugreifen kann. mit <img src="file:///android_asset/myimage.png"> aber dies scheiterte (aus offensichtlichen Gründen)Android: Wie Asset Bilder von einem entfernt geladen HTML-Seite in webview

Ich versuchte zunächst, Bilder zu laden. Mein nächster Versuch war, eine ContentProvider Klasse und Referenzbilder mit <img src="content://com.myapp.assetcontentprovider/myimage.png"> zu verwenden. Dieser Contentprovider wird wie folgt umgesetzt:

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 
} 

Wenn die HTML-Seite geladen ich im Debug-Protokoll kann sehen, dass openFile() tatsächlich aus dem WebView ausgelöst wird, und es gibt ein gültiges ParcelFileDescriptor Objekt aber immer noch das Bild wird nicht angezeigt. Es werden keine Fehlermeldungen im Protokoll angezeigt, die mir sagen würden, dass WebView das Laden/Anzeigen des Bildes verweigert hat. Irgendwelche Ideen, ob und wie das funktionieren könnte? Diese

+0

Haben Sie eine Antwort auf Ihre erste Frage (warum ‚file: //‘ -Regelung ro ‚Inhalt: //‘ ist richtig funktioniert nicht) gefunden? – Olegas

Antwort

3

ist, wie ich auf dem Java-Teil tun:

String myHTML = "< img src = \" file: ///android_asset/myimage.jpg \ ""; myWebView.loadDataWithBaseURL ("file: /// android_asset /", myHTML, "text/html", "UTF-8", "");

prost

+0

Danke für Ihre Antwort, aber es ist nicht ganz die Lösung, nach der ich gesucht habe. In meiner Anwendung wird die HTML-Seite von einer URL geladen über HTTP mit myWebView.loadUrl(). Oder schlagen Sie mit so etwas wie org.apache.http dem HTML-Code zu laden und sie dann von Hand in die Webansicht setzen mit loadDataWithBaseURL()? – brotherli

+0

Sie könnten das tun. Dies hängt jedoch davon ab, ob der heruntergeladene HTML-Code relative oder absolute Links verwendet. Ach, stellen Sie sicher, dass Ihre Vermögenswerte in der richtigen Form benannt sind. (keine Leerzeichen und seltsame Zeichen ...) –

6

OK, dank mufumbo Antwort fand ich jetzt eine funktionierende lokale Assets in der Ferne geladen HTML-Seiten mischen hacken. Seiten geladen mit dem loadUrl() Methode des WebView keine Bilder mit Datei verknüpft laden: /// android_asset/... Als Abhilfe können Sie die HTML-Seite mit org.apache.http.client.methods.HttpGet.HttpGet() holen können und dann mit loadDataWithBaseURL() zum WebView passieren. In diesem Fall lädt das WebView Ressourcen, die mit file: /// android_asset/verknüpft sind, sowie Bilder und Skripte über HTTP. Hier ist mein maßgeschneiderter webview Code:

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

Bitte beachten Sie, dass die ganze http fetching in der home-grown Utility-Klasse NetUtil gewickelt ist.

Mit dieser Klasse können HTML-Seiten von einem Webserver gerendert und statische Ressourcen wie Bilder oder Stylesheets aus dem Asset-Ordner der App geladen werden, um die Ladegeschwindigkeit zu erhöhen und Bandbreite zu sparen.

+0

Wie haben Sie es geschafft, dies für Links zu erreichen, die innerhalb der Webansicht geklickt werden? Meins funktioniert nur beim Laden der ersten Seite. – BradLaney

+0

@BradLaney @brotherli Wo bekomme ich die 'NetUtil' Klasse – GameDevGuru