10

WebView の HTML ページ内からアプリのアセット フォルダーから画像を読み込んで参照しようとしています。ほとんどの例とは異なり、HTML ページ自体は assets フォルダーにはありませんが、http 経由でサーバーから読み込まれます。この質問の背景には、デバイスから直接静止画像をロードすることにより、ロード時間 (および転送されるデータの量) を削減するパフォーマンスの改善があります。リモートで読み込まれた Web ページからローカル ファイル ストレージへのアクセスを許可することでアプリを悪用する可能性があるため、Android にいくつかの制限があるかどうかはわかりません。

最初に を使用して画像を読み込もうとしまし<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 が画像の読み込み/表示を拒否したことを示すエラー メッセージはログに表示されません。これが機能するかどうか、またどのように機能するかについてのアイデアはありますか?

4

2 に答える 2

6

OK、mufumbo の回答のおかげで、リモートで読み込まれた HTML ページにローカル アセットを混在させるための有効なハックが見つかりました。WebView のメソッドを使用してロードされたページは、loadUrl()file:///android_asset/... にリンクされた画像をロードしません。この場合、WebView は file:///android_asset/ にリンクされたリソースと、HTTP 経由の画像とスクリプトを読み込みます。これが私のカスタマイズされた webview コードです。org.apache.http.client.methods.HttpGet.HttpGet()loadDataWithBaseURL()

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

このクラスを使用すると、Web サーバーから HTML ページをレンダリングし、画像やスタイルシートなどの静的リソースをアプリのアセット フォルダーからロードして、読み込み速度を向上させ、帯域幅を節約することができます。

于 2010-10-28T14:28:34.657 に答える
3

これは私がJava部分で行う方法です:

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

乾杯

于 2010-10-21T09:19:49.660 に答える