全部产品

Android H5容器指南

更新时间:2019-03-11 11:34:24

初始化

添加依赖

  1. compile ('com.emas.hybrid:emas-hybrid-android:1.0.1.2') { transitive true}

添加权限activity到清单文件

  1. <activity android:name="android.taobao.windvane.runtimepermission.PermissionActivity">
  2. </activity>

在Application中合适的位置进行EmasHybrid的初始化工作

  1. // 自定制适配器(可选)
  2. EmasHybrid.Config.Builder builder = new EmasHybrid.Config.Builder();
  3. builder.setNavigatorAdapter(new INavigatorAdapter() {
  4. //xxx
  5. }).setStorageAdapter(new IStorageAdapter() {
  6. //xxx
  7. });
  8. EmasHybrid.getInstance()
  9. .setOpenLog(true)
  10. .setAppKey(mAppkey)
  11. .setAppSecret(mAppSecret)
  12. .setTtid(mChannelID)
  13. .setAppVersion(BuildConfig.VERSION_NAME)
  14. .setZcacheEnable(true)// 如果需要开启zcache预加载
  15. .setZcacheUrl(mCacheURL)// zcache预加载拉取地址前缀
  16. .setConfig(builder.build())// 自定制适配器,可选
  17. .init(application);

注:

  • INavigatorAdapter Navigator模块,系统提供了pop/push的实现,也可以自定义
  • IStorageAdatper Storage模块,系统提供了setItem/getItem/removeItem的默认实现,也可以自定义

撰写容器Activity

为保证最大的集成灵活性,本SDK提供Fragment形式H5容器,可以借助所提供的EmasHybridInstance将H5容器Fragment渲染至您的Activity的任意合适的位置。

注册activity

为保证内置的Navigator模块生效,请将您的Activity加入如下IntentFilter配置

  1. <intent-filter>
  2. <action android:name="android.intent.action.VIEW"/>
  3. <category android:name="android.intent.category.BROWSABLE" />
  4. <category android:name="com.emas.android.intent.category.HYBRID" />
  5. <category android:name="android.intent.category.DEFAULT"/>
  6. <data android:scheme="http"/>
  7. <data android:scheme="https"/>
  8. </intent-filter>

data标签中的scheme取决于Navigator模块所需要跳转的scheme,您可以自定义更多

将Fragment添加至Activity

在您的布局文件中合适的位置添加一个Framelayout,比如

  1. <FrameLayout
  2. android:id="@+id/root"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content">
  5. </FrameLayout>

在Activity中使用EmasHybridInstance渲染Fragment

  1. webViewFragment = EmasHybridWebViewHelper.getInstance().installWebView(
  2. this,
  3. getIntent().getData(),
  4. R.id.root,
  5. new WVWebViewClient(this) {
  6. @Override
  7. public void onPageFinished(WebView view, String url) {
  8. super.onPageFinished(view, url);
  9. Log.d("test", view.getTitle());
  10. }
  11. }, null);

注意,渲染的url保存在Intent的data中

添加返回键和回调处理

  1. @Override
  2. public boolean onKeyDown(int keyCode, KeyEvent event) {
  3. if (keyCode == KeyEvent.KEYCODE_BACK && webViewFragment != null) {
  4. boolean result = EmasHybrid.getInstance().isUseUc() ? ((WVUCWebViewFragment) webViewFragment).onBackPressed() : ((WVWebViewFragment) webViewFragment).onBackPressed();
  5. return result || super.onKeyDown(keyCode, event);
  6. }
  7. return super.onKeyDown(keyCode, event);
  8. }
  9. @Override
  10. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  11. if (EmasHybrid.getInstance().isUseUc()) {
  12. ((WVUCWebViewFragment) webViewFragment).onActivityResult(requestCode, resultCode, data);
  13. } else {
  14. ((WVWebViewFragment) webViewFragment).onActivityResult(requestCode, resultCode, data);
  15. }
  16. }
  17. @Override
  18. protected void onPause() {
  19. if (EmasHybrid.getInstance().isUseUc()) {
  20. ((WVUCWebViewFragment) webViewFragment).onPause();
  21. } else {
  22. ((WVWebViewFragment) webViewFragment).onPause();
  23. }
  24. super.onPause();
  25. }
  26. @Override
  27. protected void onResume() {
  28. if (EmasHybrid.getInstance().isUseUc()) {
  29. ((WVUCWebViewFragment) webViewFragment).onResume();
  30. } else {
  31. ((WVWebViewFragment) webViewFragment).onResume();
  32. }
  33. super.onResume();
  34. }
  35. @Override
  36. protected void onDestroy() {
  37. if (EmasHybrid.getInstance().isUseUc()) {
  38. ((WVUCWebViewFragment) webViewFragment).onDestroy();
  39. } else {
  40. ((WVWebViewFragment) webViewFragment).onDestroy();
  41. }
  42. super.onDestroy();
  43. }

使用UC内核

获取接入授权码

UCSDK需要单独的接入授权码方可使用,请联系客户对应的解决方案工程师予以申请,需要提供应用包名和证书签名SHA串码

使用命令keytool -list -v -keystore ~/.android/debug.keystore生成所需证书的SHA1哈希值

UCSDK接入

申请接入授权码在EmasHybrid初始化时通过创建UCConfig传入,示例如下

  1. EmasHybrid.UCConfig.Builder builder = new EmasHybrid.UCConfig.Builder();
  2. EmasHybrid.UCConfig ucConfig = builder
  3. .setEnable(true)
  4. .setCoreUnderWifiOnly(false)// 解除仅4G环境下载UC内核的限制
  5. .setUcSdkAppKeySec(new String[]{"KeFcdGYMAZsavbV0VprwEy4nKq+zuMW0lcn43EWXUzx2fIDEtc5MZx+l8FykIQvJ8LLQV4XT2TBun9kgUMRRdw=="})
  6. .build();
  7. EmasHybrid.getInstance()
  8. ..
  9. .setUcConfig(ucConfig)
  10. .init(application);

使用UCFragment

  1. webViewFragment = EmasHybridWebViewHelper.getInstance().installUCWebView(
  2. this,
  3. getIntent().getData(),
  4. R.id.root,
  5. new WVUCWebViewClient(this) {
  6. @Override
  7. public void onPageFinished(com.uc.webview.export.WebView view, String url) {
  8. super.onPageFinished(view, url);
  9. }
  10. }, null);
  11. @Override
  12. public boolean onKeyDown(int keyCode, KeyEvent event) {
  13. if (keyCode == KeyEvent.KEYCODE_BACK && webViewFragment != null) {
  14. boolean result = ((WVUCWebViewFragment) webViewFragment).onBackPressed();
  15. return result || super.onKeyDown(keyCode, event);
  16. }
  17. return super.onKeyDown(keyCode, event);
  18. }

其他步骤都与集成系统webview相同

确认内核类型

Useragent 信息中,如果包含 UCBrowser 字段,则是 UC 内核(如果还包含了 UCBS 字段,则是 U4 内核,否则为U3内核),如果以上字段都没有,是系统原生的内核。

可以扫下面的页面,会展示出内核的类型:

数据监控

EMAS-Hybrid提供了默认的、全面的数据监控实现,默认开启,可以在初始化的时候手动关闭

  1. EmasHybrid.getInstance()
  2. .setOpenMonitor(true)//默认为开启
  3. .init(application);

自定义自己的实现

在保留默认性能监控逻辑的基础上,客户可以自己追加实现,可选的继承类如下:

类名 作用
WVMonitorImpl.java 性能和错误监控

这里以客户自己追加实现首屏加载实现举例,首先继承自WVMonitorImpl,并实现其中两个方法,注意保证每个方法的super方法的调用

  1. public class CustomPerformanceMonitor extends WVMonitorImpl {
  2. private static long start = 0;
  3. @Override
  4. public void didPageStartLoadAtTime(String url, long time) {
  5. super.didPageStartLoadAtTime(url, time);
  6. start = time;
  7. }
  8. @Override
  9. public void didPageFinishLoadAtTime(String url, long time) {
  10. super.didPageFinishLoadAtTime(url, time);
  11. long elapse = time - start;
  12. Log.d("test", ">>> " + elapse);
  13. }
  14. }

在EmasHybrid初始化后注册到EmasHybridMonitor

  1. EmasHybrid.getInstance().xxx.init(application);
  2. EmasHybridMonitor.registerPerformanceMonitor(new CustomPerformanceMonitor());

使用JS Bridge

EMASHybrid容器接入后,您即获得了相当多的实用内置的JS API,相关的API参考文档如下:

https://help.aliyun.com/document_detail/102685.html

如果您有自己的原生实现需要通过EMASHybrid的JS Bridge暴露出能力供前端调用,也是很容易的。这里以如何扩展一个Toast为例,首先加入你的原生插件实现:

  1. public class CustomToastPlugin extends WVApiPlugin {
  2. @Override
  3. protected boolean execute(String action, String params, WVCallBackContext wvCallBackContext) {
  4. JSONObject jsonObject = null;
  5. try {
  6. jsonObject = new JSONObject(params);
  7. String content = jsonObject.optString("content");
  8. if ("long".equals(action)) {
  9. Toast.makeText(mContext, content, Toast.LENGTH_LONG).show();
  10. } else if ("short".equals(action)) {
  11. Toast.makeText(mContext, content, Toast.LENGTH_SHORT).show();
  12. }
  13. } catch (JSONException e) {
  14. e.printStackTrace();
  15. }
  16. return true;
  17. }
  18. }

再在EMASHybrid初始化后调用插件管理器注册这个插件:

  1. EmasHybridApi.registerPlugin("Toast", CustomToastPlugin.class);

这样就成功的注册了一个叫做Toast的插件,它含有两个函数short和long,需要前端传递叫做content的参数,即Toast需要显示的内容,前端可以按照下列方式调用这个JS API:

  1. let params = {
  2. content: "This is a short Toast!"
  3. }
  4. window.WindVane.call('Toast', 'short', params, function(e) {
  5. }, function(e) {
  6. alert('failure' + JSON.stringify(e));
  7. });

当然,也可以通过lib-emas来预先注册这个JS API,通过调用emas.add函数:

  1. emas.add("Toast.long")
  2. emas.add("Toast.short")

随后就可以调用这两个函数:

  1. emas.Toast.long({content: 'Hello'})
  2. emas.Toast.short({content: 'Hello'})

标准事件机制

提供了 Native 和 H5 之间互发事件的标准通讯接口,便于各业务场景下的基于统一的事件模型来通讯

Native 向 H5 发送事件

EMASHybrid提供了 WVStandardEventCenter 类,供 Native 向 H5 发送事件:

参数中,webView 是要发送事件的目标 WebView,eventName 是事件的名称(字符串),eventData 是事件的数据(iOS 是 NSDictionary *,Android 是一个 JSON Object 格式的 String)。

  1. // 向指定 WebView 发送事件。
  2. WVStandardEventCenter.postNotificationToJS(webView, eventName, eventData);
  3. // 向所有 WebView 发送事件,请谨慎使用。
  4. WVStandardEventCenter.postNotificationToJS(eventName, eventData);

随后前端中使用W3C的标准形式来接收事件:

  1. document.addEventListener('eventName', function(data) {
  2. // 这里要注意,Native 传递过来的事件参数是在 data 的 param 属性中。
  3. alert(data.param);
  4. }, false);

H5 向 Native 发送事件

EMAS Hybrid提供了发送事件的JS API供前端调用:

  1. var params = {
  2. event: 'eventName',
  3. param: {
  4. // 事件要传递的数据。
  5. }
  6. };
  7. window.WindVane.call('WVStandardEventCenter','postNotificationToNative', params, function(e) {
  8. alert('success');
  9. }, function(e) {
  10. alert('failure: ' + JSON.stringify(e));
  11. });

或者使用lib-emas的调用方式

  1. emas.WVStandardEventCenter.postNotificationToNative({...})

原生若需要接受事件,需要注册WVEventListener监听器:

  1. // 首先,需要自己实现监听用的 Listener。
  2. public class JsEventListener implements WVEventListener {
  3. @Override
  4. public WVEventResult onEvent(int id, WVEventContext ctx, Object... obj) {
  5. // 所有事件均派发到这里,WVEventId.H5TONATIVE_EVENT 表示 H5 发送过来的事件。
  6. if (id == WVEventId.H5TONATIVE_EVENT) {
  7. if (obj[0] instanceof String) {
  8. String params = (String)obj[0];
  9. // 这里的 params 是包含 event 和 param 的 JSON String,需要自行反序列化。
  10. }
  11. }
  12. return null;
  13. }
  14. }
  15. // 然后,注册监听器。
  16. WVEventService.getInstance().addEventListener(new JsEventListener());