2010-10-04 3 views
10

J'essaie de charger/référencer des images depuis le dossier des ressources de l'application à partir d'une page HTML dans un WebView. Contrairement à la plupart des exemples, la page HTML elle-même ne se trouve pas dans le dossier assets mais est chargée depuis un serveur via http. Le contexte de cette question est quelques améliorations de performance qui devraient réduire le temps de chargement (et la quantité de données transférées) en chargeant des images statiques directement à partir de l'appareil. Je ne suis pas sûr si Android a quelques restrictions ici, car il existe une certaine possibilité d'exploiter l'application en permettant l'accès au stockage de fichiers local à partir d'une page Web chargée à distance.Android: Comment référencer des images d'actif à partir d'une page html chargée à distance dans Webview

J'ai d'abord essayé de charger des images en utilisant <img src="file:///android_asset/myimage.png"> mais cela a échoué (pour des raisons évidentes). Ma prochaine tentative a été d'utiliser une classe ContentProvider et des images de référence en utilisant <img src="content://com.myapp.assetcontentprovider/myimage.png">. Ce ContentProvider est mis en œuvre comme suit:

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 
} 

Lors du chargement de la page HTML que je peux voir dans le journal de débogage qui openFile() est effectivement déclenchée de la WebView et retourne un objet ParcelFileDescriptor valide, mais encore l'image n'apparaît pas. Il n'y a aucun message d'erreur montré dans le journal qui indiquerait que WebView a refusé de charger/afficher l'image. Des idées si et comment cela pourrait fonctionner?

+0

Avez-vous trouvé une réponse à votre question initiale (pourquoi 'file: //' scheme ro 'content: //' on ne fonctionne pas correctement)? – Olegas

Répondre

3

Voilà comment je fais de la part java:

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

acclamations

+0

Merci pour votre réponse, mais ce n'est pas tout à fait la solution que je cherchais. Dans mon application, la page HTML est chargée à partir d'une URL via HTTP avec myWebView.loadUrl(). Ou proposez-vous de charger le code HTML avec quelque chose comme org.apache.http puis de le mettre manuellement dans le webview avec loadDataWithBaseURL()? – brotherli

+0

Vous pourriez le faire. Mais cela dépend si le HTML que vous téléchargez utilise des liens relatifs ou absolus. Ah, assurez-vous que vos actifs sont nommés dans le formulaire approprié. (pas d'espaces et de caractères étranges ...) –

6

OK, grâce à la réponse de mufumbo maintenant je trouve un travail hack pour mélanger les actifs locaux dans les pages HTML à distance chargés. Les pages chargées à l'aide de la méthode loadUrl() de WebView ne chargent pas les images liées à file: /// android_asset/... Pour contourner le problème, vous pouvez récupérer la page HTML en utilisant org.apache.http.client.methods.HttpGet.HttpGet(), puis la transmettre au WebView avec loadDataWithBaseURL(). Dans ce cas, WebView chargera les ressources liées à file: /// android_asset/ainsi que les images et les scripts via HTTP. Voici mon code WebView personnalisé:

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

S'il vous plaît noter que l'ensemble fetching http est enveloppé dans l'utilitaire home-grown classe NetUtil. Avec cette classe, il est possible de rendre des pages HTML à partir d'un serveur Web et de charger des ressources statiques comme des images ou des feuilles de style depuis le dossier des ressources de l'application afin d'améliorer la vitesse de chargement et la bande passante.

+0

Comment avez-vous réussi à faire fonctionner ceci pour les liens qui sont cliqués dans le webview? Le mien ne fonctionne que sur le chargement de la première page. – BradLaney

+0

@BradLaney @brotherli Où puis-je obtenir la classe 'NetUtil' – GameDevGuru

Questions connexes