全部產品
Search
文件中心

Mobile Platform as a Service:擴充 H5 容器

更新時間:Jul 26, 2024

H5 容器組件提供豐富的擴充功能,為方便使用者在更多的情境下使用 H5 容器,本文檔通過樣本來介紹以下 H5 容器擴充功能。

H5Plugin 擷取 Activity 返回的結果

在刷臉、識別等情境中,都需要啟動一個新的 Activity 以擷取 Activity 返回的結果,但是在這種情境中,JSAPI 無法直接通過重寫 H5Activity 來擷取結果。因此在使用 H5 容器時,您需要通過以下方式來擷取 Activity 返回的結果:

  1. 在自訂的 H5Plugin 中註冊 OnH5ActivityResult 回調,樣本如下:

    H5ActivityResultManager.getInstance().put(onH5ActivityResult);
    說明
    • put 方法不檢查重複註冊,開發人員需自己處理防止重複註冊。

    • 使用後,需要調用 remove 方法移除回調,一般建議在 H5Plugin 的 onRelease 方法中移除回調。樣本如下:

    H5ActivityResultManager.getInstance().remove(onH5ActivityResult);
  2. startActivityForResult 的方式啟動目的 Activity,如可以在自訂的 H5Plugin 的 handleEvent 方法中啟動,樣本如下:

    public boolean handleEvent(H5Event event, H5BridgeContext context) {
     if ("CustomJSAPI".equals(event.getAction())) {
         if (event.getActivity()!=null){
             Intent intent = new Intent(event.getActivity(), yourDestinationActivity.class);
             event.getActivity().startActivityForResult(intent,requestCode,bundle);
         }
         return true;
     }
     return false;
    }
    說明

    僅對 H5Activity 的 result 進行回調。

  3. OnH5ActivityResult 的回調方法中,將結果通過 H5BridgeContext 對象傳遞給前端。

    public interface OnH5ActivityResult {
         void onGetResult(int requestCode, int resultCode, Intent intent);
    }

自訂 H5 錯誤頁

當您需要自訂 H5 錯誤頁的時候,請按照以下步驟進行操作:

  1. 建立一個 HTML 格式的自訂錯誤頁。

     <!doctype html>
     <html lang="zh-cn">
    
     <head>
       <meta charset="utf-8" />
       <meta name="viewport" content="width=device-width,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" />
       <meta name="format-detection" content="telephone=no" />
       <title>自訂錯誤</title>
     </head>
    
     <body>
         <p>這個頁面是一個自訂錯誤頁</p>
     </body>
    
     </html>
  2. 實現 H5ErrorPageView。在 APWebView 中設定剛才建立的錯誤頁。

     public class H5ErrorPageViewImpl implements H5ErrorPageView {
         @Override
         public boolean enableShowErrorPage() {
             // true 表示啟動自訂錯誤頁
             return true;
         }
         @Override
         public void errorPageCallback(H5Page h5Page, APWebView view, String errorUrl, int statusCode, String errorMsg, String subErrorMsg) {
             // 擷取錯誤頁的 html,demo 中放到了 raw 中,也可以放在其他地方
             String html = H5ResourceManager.readRawFromResource(R.raw.custom_error, LauncherApplicationAgent.getInstance().getApplicationContext().getResources());
             // 將錯誤頁設定給 webview
             view.loadDataWithBaseURL(errorUrl, html, "text/html", "utf-8", errorUrl);
         }
     }
  3. 註冊 H5ErrorPageView。在開啟 H5 容器之前,將自訂的 H5ErrorPageView 註冊給容器。

    H5Utils.setProvider(H5ErrorPageView.class.getName(),new H5ErrorPageViewImpl());
說明

10.1.68.7 及以上版本的基準支援了新的 MPH5ErrorPageView ,方法名和使用方式與 H5ErrorPageView 一致,但是方法參數有擴充。

/**
 * 自訂網路錯誤頁面介面
 */
public interface MPH5ErrorPageView {
    /**
     * @param h5Page      page 對象
     * @param view        webview 對象
     * @param errorUrl    錯誤地址
     * @param statusCode  錯誤碼
     * @param errorMsg    錯誤描述
     * @param subErrorMsg 錯誤描述 sub
     * @param extInfo     擴充資訊,請注意判空
     * @param extObj      擴充類,請注意判空
     * @return true 表示需要展示自訂頁面,會走到下面 errorPageCallback 方法
     */
    boolean enableShowErrorPage(H5Page h5Page, APWebView view, String errorUrl, int statusCode, String errorMsg, String subErrorMsg, Bundle extInfo, Object extObj);
    /**
     * @param h5Page      page對象
     * @param view        webview 對象
     * @param errorUrl    錯誤地址
     * @param statusCode  錯誤碼
     * @param errorMsg    錯誤描述
     * @param subErrorMsg 錯誤描述 sub
     * @param extInfo     擴充資訊,請注意判空
     * @param extObj      擴充類,請注意判空
     */
    void errorPageCallback(H5Page h5Page, APWebView view, String errorUrl, int statusCode, String errorMsg, String subErrorMsg, Bundle extInfo, Object extObj);
}

開啟沈浸式狀態列

若需開啟沈浸式狀態列,可根據如下步驟實現:

說明
  • 此功能僅在 10.1.60 及以上基準版本中支援。

  • 此方法將設定所有 H5 容器開啟的 H5 頁面的狀態列顏色,如果對狀態列顏色設定有更複雜的需求,可實現 H5 容器 自訂標題列

  • 狀態列顏色設定可在容器標題列介面的 openTranslucentStatusBarSupport 方法中處理,也可在其他地方處理。

  1. H5 容器配置 中開啟 TSBS

  2. 對於使用內建標題列的開發人員,可實現 H5TransStatusBarColorProvider 介面,並通過 H5Utils.setProvider 方法將執行個體設定給 H5 容器,程式碼範例如下:

     package com.mpaas.demo.nebula;
    
     import android.graphics.Color;
    
     import com.alipay.mobile.nebula.provider.H5TransStatusBarColorProvider;
    
     public class H5TransStatusBarColorProviderImpl implements H5TransStatusBarColorProvider {
         @Override
         public int getColor() {
             return Color.argb(70, 255, 255, 255);
         }
     }

添加第三方 JavaScriptInterface

接入方通常會遇到接入第三方頁面必須要使用 JavaScriptInterface 的問題,可按照以下步驟來支援此情境:

  1. 實現外掛程式以攔截三方頁面載入事件。

  2. 擷取 WebView 並注入 JavaScript 對象。

程式碼範例如下:

package com.mpaas.demo.nebula;

import android.text.TextUtils;

import com.alibaba.fastjson.JSONObject;
import com.alipay.mobile.h5container.api.H5BridgeContext;
import com.alipay.mobile.h5container.api.H5Event;
import com.alipay.mobile.h5container.api.H5EventFilter;
import com.alipay.mobile.h5container.api.H5Param;
import com.alipay.mobile.h5container.api.H5SimplePlugin;

public class TechFinSitePlugin extends H5SimplePlugin {

    @Override
    public void onPrepare(H5EventFilter filter) {
        super.onPrepare(filter);
        filter.addAction(CommonEvents.H5_PAGE_SHOULD_LOAD_URL);
    }

    @Override
    public boolean interceptEvent(H5Event event, H5BridgeContext context) {
        String action = event.getAction();
        if (CommonEvents.H5_PAGE_SHOULD_LOAD_URL.equals(action)) {
            JSONObject params = event.getParam();
            String url = params.getString(H5Param.LONG_URL);
            if (!TextUtils.isEmpty(url) && url.contains("tech.antfin.com")) {
                event.getH5page().getWebView().addJavascriptInterface(new TechFinJavaScriptInterface(), "techFinBridge");
            }
        }

        return false;
    }
}
說明

切勿在 interceptEvent 方法中返回 true ,否則將影響容器載入頁面。

package com.mpaas.demo.nebula;

import android.webkit.JavascriptInterface;

public class TechFinJavaScriptInterface {

    @JavascriptInterface
    @com.uc.webview.export.JavascriptInterface
    public String whoAmI() {
        return "It is tech fin.";
    }
}
說明

系統核心和 UC 核心使用的註解類不同,必須要相容這兩個註解類。

為 H5 容器添加過場動畫

要為 H5 容器添加過場動畫,只需在專案的 res/anim 檔案夾下添加動畫資源即可。操作步驟如下:

  1. 在專案的 res 檔案夾下建立 anim 檔案夾,如有可跳過。

  2. 將過程動畫的資源檔添加到 anim 檔案夾。H5 容器根據資源檔的檔案名稱自動識別資源檔,因此資源檔的檔案名稱只能為 h5_slide_out_right.xmlh5_slide_out_left.xmlh5_slide_in_right.xmlh5_slide_in_left.xml。您可以參考以下樣本,建立您自己的資源檔。

    • h5_slide_out_right.xml

      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
      <translate
        android:fromXDelta="0%"
        android:toXDelta="100%"
        android:duration="300" />
      </set>
    • h5_slide_out_left.xml

      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
      <translate
        android:fromXDelta="0%"
        android:toXDelta="-100%"
        android:duration="300" />
      </set>
    • h5_slide_in_right.xml

      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
      <translate
        android:fromXDelta="100%"
        android:toXDelta="0"
        android:duration="300" />
      </set>
    • h5_slide_in_left.xml

      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
      <translate
        android:fromXDelta="-100%"
        android:toXDelta="0%"
        android:duration="300" />
      </set>

為 H5 容器的 JSAPI 配置黑名單

指定網域名稱調用容器 JSAPI 做許可權管控時,可以通過配置黑名單的方式處理。具體步驟如下:

  1. 繼承 H5JSApiPermissionProvider 類,重寫 hasDomainPermission 方法。hasDomainPermission 方法兩個入參分別為 actionurlaction 表示自訂 JSAPI 的事件名稱,url 表示當前頁面訪問的網域名稱地址。傳回值為 boolean 類型。true 表示可以處理該事件,false 表示無許可權處理該事件。以下為 Demo 代碼,僅供參考。

    public class H5JSApiPermissionProviderImpl implements H5JSApiPermissionProvider {
         private static final List blackList = new ArrayList<String>();
         static {
         // 在黑名單列表中的 url 將無許可權執行 JSAPI 等相關事件
         blackList.add("https://mcube-prod.cn-hangzhou.oss.aliyuncs.com/ONEX4B905F1032156-MUAT/20210728/0.0.0.1_all/nebula/fallback/www/index.html");
         }
    
         @override
         public boolean hasDomainPermission(String action, String url) {
             // 接入者可以根據 action 名稱和 url 來判斷是否有許可權執行當前的 action。
             // action 就是定義的 JSAPI 事件,返回 true 代表可以處理該事件,返回 false 代表無許可權處理該事件
             if (blackList.contains(url)) {
                 return false;
             }
             return true;
         }
         @override
         public boolean hasThisPermission(String permission, String url) {
             return true;
         }
    }
  2. 在架構初始化完成之後設定 Provider

    H5Utils.setProvider(H5JSApiPermissionProvider.class.getName(), new H5JSApiPermissionProviderImpl());