Android 如何使用 WebView 加載 HTML 字符串和處理轉譯字符

Android 如何使用 WebView 加載 HTML 字符串和處理轉譯字符

css bug

在 WebView 中編譯 Web 應用

如果您希望在客戶端應用中提供 Web 應用(或只是網頁),則可以使用 WebView 執行該操作。
WebView 類是 Android 的 View 類的擴展,可讓您將網頁顯示爲 Activity 佈局的一部分。
它不會包含功能全面的網絡瀏覽器的任何功能,例如導航控件或地址欄。
WebView 默認只顯示網頁。

使用 WebView 非常有用的一種常見情形是,您希望在應用中提供可能需要更新的信息,例如最終用戶協議或用戶指南。
在 Android 應用中,您可以創建一個包含 WebView 的 Activity,然後使用它來顯示在線託管的文檔。

另一種 WebView 可能會有所幫助的情形是,如果您的應用向用戶提供始終需要互聯網連接才能檢索數據的數據(例如電子郵件)。
在這種情況下,您可能會發現相比於執行網絡請求,然後解析數據並在 Android 佈局中呈現數據,在 Android 應用中編譯 WebView 以顯示包含所有用戶數據的網頁更加輕鬆。
您可以改爲設計一個專爲 Android 設備定製的網頁,然後在加載該網頁的 Android 應用中實現 WebView。

本文檔向您介紹瞭如何開始使用 WebView 以及如何執行其他操作,例如處理網頁導航以及將網頁中的 JavaScript 綁定到 Android 應用中的客戶端代碼。

  1. 在 Activity 佈局中添加 WebView

要在佈局中爲應用添加 WebView,請將以下代碼添加到 Activity 的佈局 XML 文件中

    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    />

  1. 要在 WebView 中加載網頁,請使用 loadUrl()

    WebView myWebView = (WebView) findViewById(R.id.webview);
    myWebView.loadUrl("http://www.example.com");

在 Activity 的 onCreate() 方法中嚮應用添加 WebView

    WebView myWebView = new WebView(activityContext);
    setContentView(myWebView);
    

使用以下命令加載網頁:

    myWebView.loadUrl("https://www.example.com");

通過 HTML 字符串加載網址:

    // Create an unencoded HTML string, 
    // then convert the unencoded HTML string into bytes, encode
    // it with Base64, and load the data.
    String unencodedHtml = "&lt;html&gt;&lt;body&gt;'%23' is the percent code for ‘#‘ &lt;/body&gt;&lt;/html&gt;";
    String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING);
    // Base64 HTML String
    myWebView.loadData(encodedHtml, "text/html", "base64");
    

注意:此 HTML 可以執行的操作受到限制。如需詳細瞭解編碼選項,請參閱 loadData() 和 loadDataWithBaseURL()。

https://developer.android.com/guide/webapps/webview?hl=zh-cn

https://developer.android.com/reference/android/webkit/WebView?hl=zh-cn#loadData


https://developer.android.com/reference/android/webkit/WebView?hl=zh-cn#loadDataWithBaseURL

// baseUrl 可以指定HTML代碼片段中相關資源的相對根路徑
public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)

solution

  1. WebView 加載 HTML 字符串

  1. 處理轉譯字符

regex 正則表達式

// &lt; &gt; 替換成對應的 <、>
const left = HTMLString.replaceAll("&lt;", "<");

const right = HTMLString.replaceAll("&gt;", ">");


const html = HTMLString.replaceAll("<img", "<img style='max-width:90%; height:auto;'");

demo

package com.example.webview_app;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.webkit.WebView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
  private WebView testWebView;
  private TextView testTextView;
  // Android 如何使用 WebView 加載 HTML 字符串和處理轉譯字符
  private String htmlString = "&lt;body&gt;&lt;header&gt;&lt;h1&gt;隱私保密條款&lt;/h1&gt;&lt;/header&gt;&lt;main&gt;&lt;article&gt;&lt;h3&gt;六、《隱私保密條款》如何更新&lt;/h3&gt;&lt;p&gt;隨着法律法規的出臺或修訂,本網站的《隱私保密條款》可能會發生變更。條款內容變更後,本網站會以公告或站內信的形式通知用戶本網站對條款所做的任何變更,或以其他適當方式提醒用戶相關內容的更新。&lt;/p&gt;&lt;h3&gt;七、如何聯繫客服&lt;/h3&gt;&lt;p&gt;如用戶對本《隱私權專項條款》內容有任何疑問、意見或建議,用戶可通過客服渠道聯繫,官方客服電話爲:&lt;ahref=&quot;tel:+400-099-8987&quot;&gt;400-099-8987&lt;/a&gt;,同時用戶也可以聯繫本網站的“在線客服”。&lt;/p&gt;&lt;h3&gt;八、法律適用、管轄與其他&lt;/h3&gt;&lt;p&gt;8.1條款之效力、解釋、變更、執行與爭議解決均適用中華人民共和國法律,如無相關法律規定的,則應參照通用國際商業慣例和(或)行業慣例。&lt;/p&gt;&lt;p&gt;8.2因本條款產生之爭議,應依照中華人民共和國法律予以處理,並以上海市閔行區人民法院爲第一審管轄法院。&lt;/p&gt;&lt;/article&gt;&lt;/main&gt;&lt;footer&gt;&lt;imgsrc=&quot;https://cdn.xgqfrms.xyz/logo/logo.png&quot;alt=&quot;logo.png&quot;&gt;&lt;pclass=&quot;copyright&quot;&gt;copyright&amp;copy;xgqfrms2020~forever&lt;/p&gt;&lt;/footer&gt;&lt;!--js--&gt;&lt;script&gt;constlog=console.log;&lt;/script&gt;&lt;/body&gt;";
  // private static final String htmlString = "
  // &lt;body&gt;
  //   &lt;header&gt;
  //     &lt;h1&gt;隱私保密條款&lt;/h1&gt;
  //   &lt;/header&gt;
  //   &lt;main&gt;
  //     &lt;article&gt;
  //       &lt;h3&gt;六、《隱私保密條款》如何更新&lt;/h3&gt;
  //       &lt;p&gt;隨着法律法規的出臺或修訂,本網站的《隱私保密條款》可能會發生變更。條款內容變更後,本網站會以公告或站內信的形式通知用戶本網站對條款所做的任何變更,或以其他適當方式提醒用戶相關內容的更新。&lt;/p&gt;
  //       &lt;h3&gt;七、如何聯繫客服&lt;/h3&gt;
  //       &lt;p&gt;如用戶對本《隱私權專項條款》內容有任何疑問、意見或建議,用戶可通過客服渠道聯繫,官方客服電話爲:&lt;a href=&quot;tel:+400-099-8987&quot;&gt;400-099-8987&lt;/a&gt; ,同時用戶也可以聯繫本網站的“在線客服”。&lt;/p&gt;
  //       &lt;h3&gt;八、法律適用、管轄與其他&lt;/h3&gt;
  //       &lt;p&gt;8.1 條款之效力、解釋、變更、執行與爭議解決均適用中華人民共和國法律,如無相關法律規定的,則應參照通用國際商業慣例和(或)行業慣例。&lt;/p&gt;
  //       &lt;p&gt;8.2 因本條款產生之爭議,應依照中華人民共和國法律予以處理,並以上海市閔行區人民法院爲第一審管轄法院。&lt;/p&gt;
  //     &lt;/article&gt;
  //   &lt;/main&gt;
  //   &lt;footer&gt;
  //     &lt;img src=&quot;https://cdn.xgqfrms.xyz/logo/logo.png&quot; alt=&quot;logo.png&quot;&gt;
  //     &lt;p class=&quot;copyright&quot;&gt;copyright&amp;copy; xgqfrms 2020 ~ forever&lt;/p&gt;
  //   &lt;/footer&gt;
  //   &lt;!-- js --&gt;
  //   &lt;script&gt;
  //     const log = console.log;
  //   &lt;/script&gt;
  // &lt;/body&gt;
  // ";

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initWidgets(savedInstanceState);
  }

  private void initWidgets(Bundle savedInstanceState) {
    testWebView = findViewById(R.id.webView);
    testTextView = findViewById(R.id.textView);
    // 1. 開啓 WebView 對 js 加載的支持
    testWebView.getSettings().setJavaScriptEnabled(true);
    // 3. WebView 上添加 js 方法的接口實現類(new 實例化)
    testWebView.addJavascriptInterface(new JsInterface(), "JsLauncher");
    // ✅ Java 中定義的接口名,✅ 要在 js 中使用的方法名
    // webView.addJavascriptInterface(new jsMethodsObjectInterface(), "jsMethodsObjectName");
    // 4. 加載 file:///android_asset/ URL (local html)
    // testWebView.loadUrl("file:///android_asset/index.html");
    // ❓ android_asset 相對目錄, ✅ android_asset !== android_assets ❌
    // 5. 加載 HTTP URL (server html)
    // testWebView.loadUrl("https://www.cnblogs.com/xgqfrms/p/12697742.html");
    // 6. 加載 HTMl 字符串
    // img 自適應 css
    // htmlString = htmlString.replaceAll("width=\"\\d+\"", "width=\"100%\"").replaceAll("height=\"\\d+\"", "height=\"auto\"");
    htmlString = htmlString.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", "\"");
    // baseUrl 可以指定HTML代碼片段中相關資源的相對根路徑
    // public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl);
    testWebView.loadDataWithBaseURL("https://xgqfrms.xyz", htmlString, "text/html", "UTF-8", null);
  }
}


"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2020-10-01
 * @modified
 *
 * @description
 * @difficulty Easy Medium Hard
 * @complexity O(n)
 * @augments
 * @example
 * @link
 * @solutions
 *
 * @best_solutions
 *
 */

const log = console.log;

const html = `
&lt;body&gt;
  &lt;header&gt;
    &lt;h1&gt;隱私保密條款&lt;/h1&gt;
  &lt;/header&gt;
  &lt;main&gt;
    &lt;article&gt;
      &lt;h3&gt;六、《隱私保密條款》如何更新&lt;/h3&gt;
      &lt;p&gt;隨着法律法規的出臺或修訂,本網站的《隱私保密條款》可能會發生變更。條款內容變更後,本網站會以公告或站內信的形式通知用戶本網站對條款所做的任何變更,或以其他適當方式提醒用戶相關內容的更新。&lt;/p&gt;
      &lt;h3&gt;七、如何聯繫客服&lt;/h3&gt;
      &lt;p&gt;如用戶對本《隱私權專項條款》內容有任何疑問、意見或建議,用戶可通過客服渠道聯繫,官方客服電話爲:&lt;a href=&quot;tel:+400-099-8987&quot;&gt;400-099-8987&lt;/a&gt; ,同時用戶也可以聯繫本網站的“在線客服”。&lt;/p&gt;
      &lt;h3&gt;八、法律適用、管轄與其他&lt;/h3&gt;
      &lt;p&gt;8.1 條款之效力、解釋、變更、執行與爭議解決均適用中華人民共和國法律,如無相關法律規定的,則應參照通用國際商業慣例和(或)行業慣例。&lt;/p&gt;
      &lt;p&gt;8.2 因本條款產生之爭議,應依照中華人民共和國法律予以處理,並以上海市閔行區人民法院爲第一審管轄法院。&lt;/p&gt;
    &lt;/article&gt;
  &lt;/main&gt;
  &lt;footer&gt;
    &lt;img src=&quot;https://cdn.xgqfrms.xyz/logo/logo.png&quot; alt=&quot;logo.png&quot;&gt;
    &lt;p class=&quot;copyright&quot;&gt;copyright&amp;copy; xgqfrms 2020 ~ forever&lt;/p&gt;
  &lt;/footer&gt;
  &lt;!-- js --&gt;
  &lt;script&gt;
    const log = console.log;
  &lt;/script&gt;
&lt;/body&gt;
`;

// copy(html.replaceAll(` `, ``));

const htmlString = html.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", "\"");
// TypeError: html.replaceAll is not a function

// const htmlString = html.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", "\"");
// TypeError: html.replaceAll is not a function
// const htmlString = html.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, "\"");

let htmlString = ``;

if (``.replaceAll) {
  htmlString = html.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", "\"");
} else {
  htmlString = html.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, "\"");
}

log(`htmlString =`, htmlString);

log(`"".replace`, ``.replace);
log(`"".replaceAll`, ``.replaceAll);
/*

"".replace [Function: replace]
"".replaceAll undefined

*/


Android 上 WebView 圖片寬度自適應

多種適配方案

  1. viewport

  2. css media query

  3. img 自適應

refs

https://www.jianshu.com/p/0eb85fc7acc2

https://www.jianshu.com/p/6e69332cf946

String data = Html.fromHtml(content).toString();

data = data.replaceAll("width=\"\\d+\"", "width=\"100%\"").replaceAll("height=\"\\d+\"", "height=\"auto\"");

webview.loadDataWithBaseURL("http://webhost.net", data, "text/html", "UTF-8", null);

webview.getSettings().setJavaScriptEnabled(true);

String varjs = "<script type='text/javascript'> 
  window.onload = function()  {
     var $img = document.getElementsByTagName('img');
     for(var p in  $img){
       $img[p].style.width = '100%';
       $img[p].style.height ='auto';
     }
   }
 </script>";

webview.loadDataWithBaseURL("http://webhost.net",  varjs + data, "text/html", "UTF-8", null);

https://www.jianshu.com/p/a18b70c2fa90



©xgqfrms 2012-2020

www.cnblogs.com 發佈文章使用:只允許註冊用戶纔可以訪問!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章