H5 容器组件提供丰富的扩展功能,为方便用户在更多的场景下使用 H5 容器,本文档通过示例来介绍以下 H5 容器扩展功能。
H5Plugin 获取 Activity 返回的结果
在刷脸、识别等场景中,都需要启动一个新的 Activity 以获取 Activity 返回的结果,但是在这种场景中,JSAPI 无法直接通过重写 H5Activity 来获取结果。因此在使用 H5 容器时,您需要通过以下方式来获取 Activity 返回的结果:
在自定义的 H5Plugin 中注册
OnH5ActivityResult
回调,示例如下:H5ActivityResultManager.getInstance().put(onH5ActivityResult);
说明put
方法不检查重复注册,开发者需自己处理防止重复注册。使用后,需要调用
remove
方法移除回调,一般建议在 H5Plugin 的onRelease
方法中移除回调。示例如下:
H5ActivityResultManager.getInstance().remove(onH5ActivityResult);
用
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 进行回调。
在
OnH5ActivityResult
的回调方法中,将结果通过H5BridgeContext
对象传递给前端。public interface OnH5ActivityResult { void onGetResult(int requestCode, int resultCode, Intent intent); }
自定义 H5 错误页
当您需要自定义 H5 错误页的时候,请按照以下步骤进行操作:
新建一个 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>
实现
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); } }
注册
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
方法中处理,也可在其他地方处理。
在 H5 容器配置 中开启
TSBS
。对于使用内置标题栏的开发者,可实现
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
的问题,可按照以下步骤来支持此场景:
实现插件以拦截三方页面加载事件。
获取 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
文件夹下添加动画资源即可。操作步骤如下:
在项目的
res
文件夹下新建anim
文件夹,如有可跳过。将过程动画的资源文件添加到
anim
文件夹。H5 容器根据资源文件的文件名自动识别资源文件,因此资源文件的文件名只能为h5_slide_out_right.xml
、h5_slide_out_left.xml
、h5_slide_in_right.xml
或h5_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 做权限管控时,可以通过配置黑名单的方式处理。具体步骤如下:
继承
H5JSApiPermissionProvider
类,重写hasDomainPermission
方法。hasDomainPermission
方法两个入参分别为action
和url
。action
表示自定义 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; } }
在框架初始化完成之后设置
Provider
。H5Utils.setProvider(H5JSApiPermissionProvider.class.getName(), new H5JSApiPermissionProviderImpl());