您可以提供網頁式內容,例如 HTML、JavaScript 和 CSS:以便您的應用程式使用靜態編譯成應用程式 而非透過網際網路擷取
應用程式內容不需要連上網際網路,也不需要耗用使用者的頻寬。如果
內容只為WebView
設計,也就是說
這取決於與原生應用程式通訊,使用者不會意外
載入 Chrome 瀏覽器。
不過,應用程式內容有一些缺點。更新網頁式內容 必須發布新的應用程式更新, 網站內容與裝置上的應用程式內容結合 使用者的應用程式版本過舊
WebViewAssetLoader
WebViewAssetLoader
是
能以靈活且有效率的方式,載入應用程式內容
WebView
物件。這個類別支援
包括:
- 透過 HTTP(S) 網址載入內容以與相同來源相容 政策。
- 正在載入 JavaScript、CSS、圖片和 iframe 等子資源。
在主要活動檔案中加入 WebViewAssetLoader
。以下是
從素材資源資料夾載入簡易網頁內容的範例:
Kotlin
private class LocalContentWebViewClient(private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() { @RequiresApi(21) override fun shouldInterceptRequest( view: WebView, request: WebResourceRequest ): WebResourceResponse? { return assetLoader.shouldInterceptRequest(request.url) } // To support API < 21. override fun shouldInterceptRequest( view: WebView, url: String ): WebResourceResponse? { return assetLoader.shouldInterceptRequest(Uri.parse(url)) } }
Java
private static class LocalContentWebViewClient extends WebViewClientCompat { private final WebViewAssetLoader mAssetLoader; LocalContentWebViewClient(WebViewAssetLoader assetLoader) { mAssetLoader = assetLoader; } @Override @RequiresApi(21) public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { return mAssetLoader.shouldInterceptRequest(request.getUrl()); } @Override @SuppressWarnings("deprecation") // To support API < 21. public WebResourceResponse shouldInterceptRequest(WebView view, String url) { return mAssetLoader.shouldInterceptRequest(Uri.parse(url)); } }
您的應用程式必須根據自身需求設定 WebViewAssetLoader
例項。
下一節也有範例
建立應用程式內素材資源和資源
WebViewAssetLoader
依賴
PathHandler
執行個體,載入與指定資源路徑相對應的資源。雖然你
就能實作這個介面,根據應用程式的需求來擷取資源,
Webkit 程式庫套裝組合
AssetsPathHandler
敬上
和
ResourcesPathHandler
。
分別載入 Android 素材資源和資源
如要開始使用,請建立應用程式的素材資源和資源。一般而言, :
- HTML、JavaScript 和 CSS 等文字檔案屬於素材資源。
- 映像檔和其他二進位檔案屬於資源。
如要在專案中加入文字型網路檔案,請按照下列步驟操作:
- 在 Android Studio 中,於應用程式 > 上按一下滑鼠右鍵 >src >main 資料夾 然後選擇「New」(新增) > Directory。
- 將資料夾命名為「assets」。
- 在「assets」資料夾上按一下滑鼠右鍵,然後依序點選「新增」>「新增」檔案。
輸入
index.html
,然後按下 Return 鍵或 Enter 鍵。 - 重複上述步驟,為
stylesheet.css
。 - 在您建立的空白檔案中,填入接下來兩組程式碼中的內容 樣本。
```html
<!-- index.html content -->
<html>
<head>
<!-- Tip: Use relative URLs when referring to other in-app content to give
your app code the flexibility to change the scheme or domain as
necessary. -->
<link rel="stylesheet" href="/assets/stylesheet.css">
</head>
<body>
<p>This file is loaded from in-app content.</p>
<p><img src="/res/drawable/android_robot.png" alt="Android robot" width="100"></p>
</body>
</html>
```
```css
<!-- stylesheet.css content -->
body {
background-color: lightblue;
}
```
如要在專案中新增圖片式網路檔案,請按照下列步驟操作:
下載
Android_symbol_green_RGB.png
敬上 檔案複製到本機電腦將檔案重新命名為
android_robot.png
。手動將檔案移至專案的
main/res/drawable
目錄: 。
圖 4 顯示您新增的圖片以及上述程式碼範例中的文字 顯示在應用程式中的結果
如要完成這個應用程式,請按照下列步驟操作:
註冊處理常式並設定
AssetLoader
,方法是新增 將下列程式碼新增至onCreate()
方法:Kotlin
val assetLoader = WebViewAssetLoader.Builder() .addPathHandler("/assets/", AssetsPathHandler(this)) .addPathHandler("/res/", ResourcesPathHandler(this)) .build() webView.webViewClient = LocalContentWebViewClient(assetLoader)
Java
final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder() .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this)) .addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this)) .build(); mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
將下列程式碼加入
onCreate()
方法,即可載入內容:Kotlin
webView.loadUrl("https://appassets.androidplatform.net/assets/index.html")
Java
mWebView.loadUrl("https://appassets.androidplatform.net/assets/index.html");
結合應用程式內容和您網站上的資源
應用程式可能需要載入
例如由您網站 CSS 設定樣式的應用程式內 HTML 頁面。
WebViewAssetLoader
支援此用途。如果沒有註冊
PathHandler
執行個體可以找到指定路徑的資源,WebView
會下降
即可返回從網際網路載入內容。如果將應用程式內內容與
請保留網站資源的目錄路徑,例如 /assets/
或
/resources/
,用於應用程式內資源。請避免儲存
打造更多專屬網站
Kotlin
val assetLoader = WebViewAssetLoader.Builder() .setDomain("example.com") // Replace this with your website's domain. .addPathHandler("/assets/", AssetsPathHandler(this)) .build() webView.webViewClient = LocalContentWebViewClient(assetLoader) val inAppHtmlUrl = "https://example.com/assets/index.html" webView.loadUrl(inAppHtmlUrl) val websiteUrl = "https://example.com/website/data.json" // JavaScript code to fetch() content from the same origin. val jsCode = "fetch('$websiteUrl')" + ".then(resp => resp.json())" + ".then(data => console.log(data));" webView.evaluateJavascript(jsCode, null)
Java
final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder() .setDomain("example.com") // Replace this with your website's domain. .addPathHandler("/assets/", new AssetsPathHandler(this)) .build(); mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader)); String inAppHtmlUrl = "https://example.com/assets/index.html"; mWebView.loadUrl(inAppHtmlUrl); String websiteUrl = "https://example.com/website/data.json"; // JavaScript code to fetch() content from the same origin. String jsCode = "fetch('" + websiteUrl + "')" + ".then(resp => resp.json())" + ".then(data => console.log(data));"; mWebView.evaluateJavascript(jsCode, null);
觀看以下網站的 WebView
示範:
GitHub
範例,瞭解用於擷取網站代管 JSON 資料的應用程式內 HTML 網頁範例。
loadDataWithBaseURL
如果您的應用程式只需要載入 HTML 網頁,且不需要攔截
子資源,請考慮使用
loadDataWithBaseURL()
、
這項操作不需要應用程式素材資源您可以使用,如以下程式碼所示
範例:
Kotlin
val html = "<html><body><p>Hello world</p></body></html>" val baseUrl = "https://example.com/" webView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl)
Java
String html = "<html><body><p>Hello world</p></body></html>"; String baseUrl = "https://example.com/"; mWebView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl);
請謹慎選擇引數值,請把握以下幾項重點:
baseUrl
:這是 HTML 內容載入時使用的網址。這必須是 HTTP(S) 網址。data
:這是您要以字串形式顯示的 HTML 內容。mimeType
:通常必須設為text/html
。encoding
:如果baseUrl
是 HTTP(S) 網址,則不使用此方法,因此 已設為null
。historyUrl
:這是與baseUrl
相同的值。
我們強烈建議您使用 HTTP(S) 網址做為 baseUrl
,這有助於
請確保您的應用程式遵循相同來源政策。
如果找不到適合內容的baseUrl
,且想要使用
loadData()
,
你就必須使用
百分比編碼
或
Base64
編碼。
強烈建議選用 Base64 編碼,並使用 Android API 進行編碼
以程式輔助的方式建構內容,如以下程式碼範例所示:
Kotlin
val encodedHtml: String = Base64.encodeToString(html.toByteArray(), Base64.NO_PADDING) webView.loadData(encodedHtml, mimeType, "base64")
Java
String encodedHtml = Base64.encodeToString(html.getBytes(), Base64.NO_PADDING); mWebView.loadData(encodedHtml, mimeType, "base64");
應避免的事項
你可以透過多種方式載入應用程式內容,但我們強烈建議你 針對他們:
- 系統會將
file://
個網址和data:
網址視為不透明來源。 因此他們無法運用各種強大的網路 API,例如fetch()
或XMLHttpRequest
。loadData()
內部使用data:
網址,因此建議使用WebViewAssetLoader
或loadDataWithBaseURL()
。 - 雖然
WebSettings.setAllowFileAccessFromFileURLs()
敬上 和WebSettings.setAllowUniversalAccessFromFileURLs()
。 可協助解決file://
個網址的問題,因此建議您不要設定 導致這些事件傳送給true
,因為這樣會導致應用程式容易遭受檔案型攻擊 入侵建議您在所有 API 級別中明確地將這些屬性設為false
。 以獲得最強大的安全防護 - 基於相同的理由,我們建議不要使用
file://android_assets/
和file://android_res/
個網址。AssetsHandler
及ResourcesHandler
類別的用途是直接取代。 - 避免使用
MIXED_CONTENT_ALWAYS_ALLOW
。 一般來說,這項設定並非必要,會降低應用程式的安全性。 我們建議透過 HTTP 或 HTTPS—做為網站的資源MIXED_CONTENT_COMPATIBILITY_MODE
敬上 或MIXED_CONTENT_NEVER_ALLOW
, 。