首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Android WebView 中獲取 Apple Touch Icon 的最佳實踐

     編輯:Java 相關知識

前言:為什麼需要 Touch Icon?

在 iOS 設備普及的今天,用戶習慣將常用網頁「添加到主屏幕」。Apple 為此定義了 apple-touch-icon 標準,讓網頁能像原生 App 一樣擁有精美的桌面圖標。然而,Android 系統早期缺乏統一標準,開發者在 WebView 中往往只能依賴解析 Apple 的 Touch Icon 來實現類似功能。

標準 Touch Icon 寫法回顧

網頁通常在 <head> 中聲明多種尺寸的圖標,以適配不同設備:

<link rel="apple-touch-icon" href="/custom_icon.png">
<link rel="apple-touch-icon" sizes="76x76" href="touch-icon-ipad.png">
<link rel="apple-touch-icon" sizes="120x120" href="touch-icon-iphone-retina.png">
<link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad-retina.png">

若不希望 iOS 自動添加光澤與圓角,可使用 apple-touch-icon-precomposed。

Android WebView 內建回調的缺陷

WebView 提供 onReceivedTouchIconUrl(WebView view, String url, boolean precomposed) 回調,但在實戰中存在四大痛點:

  1. URL 無規律:無法從 URL 推斷尺寸;
  2. 聲明順序不可靠:HTML 編寫順序隨意,回調觸發順序不可預期;
  3. 缺失 sizes 屬性:回調不返回 sizes,難以選擇最適圖標;
  4. 下載效率低:若下載所有圖標再本地縮放,浪費流量與時間。

改進方案:JavaScript 注入解析 DOM

既然 WebView 內建 API 不足,我們可以注入 JS 腳本,主動掃描 <link> 標籤,提取完整屬性並以 JSON 回傳給 Java 層。

核心 JavaScript 代碼

var touchIcons = [];
function gatherTouchIcons(elements) {
    for (var i = 0; i < elements.length; i++) {
        var el = elements[i];
        var size = el.hasAttribute('sizes') ? el.sizes[0] : '';
        touchIcons.push({ sizes: size, rel: el.rel, href: el.href });
    }
}
function obtainTouchIcons() {
    var normal = document.querySelectorAll("link[rel='apple-touch-icon']");
    var precomposed = document.querySelectorAll("link[rel='apple-touch-icon-precomposed']");
    gatherTouchIcons(normal);
    gatherTouchIcons(precomposed);
    window.app_native.onReceivedTouchIcons(document.URL, JSON.stringify(touchIcons));
}
obtainTouchIcons();

Java 端接收與加載

webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsObject(), "app_native");
webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        String js = loadJsFromAssets("touchicon.js"); // 從 assets 讀取上述 JS
        view.loadUrl("javascript:" + js);
    }
});

private class JsObject {
    @JavascriptInterface
    public void onReceivedTouchIcons(String url, String json) {
        Log.i(TAG, "TouchIcons: " + json);
        // 解析 JSON,按尺寸/設備像素比選擇最佳圖標
    }
}

返回的 JSON 結構示例

[
  {"sizes":"72x72", "rel":"apple-touch-icon-precomposed", "href":"https://.../H5-72x72.png"},
  {"sizes":"114x114", "rel":"apple-touch-icon-precomposed", "href":"https://.../H5-114x114.png"},
  {"sizes":"57x57", "rel":"apple-touch-icon-precomposed", "href":"https://.../H5-57x57.png"},
  {"sizes":"", "rel":"apple-touch-icon-precomposed", "href":"https://.../H5-0x0.png"}
]

拿到結構化數據後,即可根據設備密度、首選尺寸邏輯挑選最優圖標,避免盲目下載。

Google 的長遠佈局:Web App Manifest

Google 已推出 <link rel="manifest" href="manifest.json"> 標準,在 JSON 中統一定義圖標、啟動頁、顯示模式等:

{
  "name": "My Web App",
  "icons": [
    {"src": "icon-48.png", "sizes": "48x48", "type": "image/png", "density": "1.0"},
    {"src": "icon-192.png", "sizes": "192x192", "type": "image/png", "density": "4.0"}
  ],
  "start_url": "index.html",
  "display": "standalone"
}

但受限於普及率,短期內仍需兼容 Apple Touch Icon。採用「JS 注入 + JSON 回傳」方案,可在過渡期優雅解決 Android 端圖標獲取難題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved