# 开发插件
# 集成使用
插件本质是一个 apk 文件。所以在一个空的 android 项目上开发即可。
# 创建一个空的Android项目
如果已经有空项目请忽略
使用 AndroidStudio 创建一个空的项目。
这边 AGP(Android Gradle Plugin)
使用的是 8.0 版本
编译脚本使用 Kotlin DSL(build.gradle.kts)
这边的主要目录结构
MyPlugin/
├── app/
│ ├── src/main/java/com.sample.myplugin/
│ │ └──MyJSViewPlugin.java
│ └──build.gradle.kts
├── gradle/
├── settings.gradle.kts
└── build.gradle.kts
2
3
4
5
6
7
8
9
接下来的文档使用以上环境来讲解。如果自身项目环境有差异请自行调整,随机应变。
# 添加 Maven 仓库
插件的 SDK 被上传到一个私有的 Maven 上,所以要额外添加一个仓库地址。
maven {
// 仓库地址
url = uri("http://nexus.cluster.qcast.cn/repository/maven-releases/")
// 高版本 gradle 要求地址是 https 协议,添加这个忽略协议要求
isAllowInsecureProtocol = true
}
2
3
4
5
6
文件./MyPlugin/settings.gradle.kts
:
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven {
url = uri("http://nexus.cluster.qcast.cn/repository/maven-releases/")
isAllowInsecureProtocol = true
}
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("http://nexus.cluster.qcast.cn/repository/maven-releases/")
isAllowInsecureProtocol = true
}
}
}
rootProject.name = "MyPlugin"
include(":app")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 添加gradle插件依赖
文件./MyPlugin/build.gradle.kts
:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.1.1" apply false
id("jsview-plugin-asm") version "1.0.0" apply false
}
2
3
4
5
对于老版本的 Gradle 是这样配置:
classpath "com.qcode.jsviewplugin:jsview-plugin-asm:1.0.0"
在文件./MyPlugin/app/build.gradle.kts
中添加:
plugins {
id("com.android.application")
id("jsview-plugin-asm")
}
...
2
3
4
5
6
# 添加插件 sdk 依赖
// JSView插件依赖
annotationProcessor("com.qcode.jsviewplugin:annotation-processor:1.0.0")
implementation("com.qcode.jsviewplugin:jsview-plugin-base:1.0.0")
2
3
文件./MyPlugin/app/build.gradle.kts
:
plugins {
id("com.android.application")
id("jsview-plugin-asm")
}
android {
namespace = "com.sample.myplugin"
compileSdk = 33
...
}
dependencies {
...
// JSView插件依赖
annotationProcessor("com.qcode.jsviewplugin:jsview-plugin-annotation-processor:1.0.0")
implementation("com.qcode.jsviewplugin:jsview-plugin-base:1.0.0")
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建插件
创建一个类继承JSViewPluginBase
并且使用 JSViewPlugin
注解这个类。
package com.sample.myplugin;
import com.qcode.jsviewpluginbase.JSViewPlugin;
import com.qcode.jsviewpluginbase.JSViewPluginBase;
import com.qcode.jsviewpluginbase.JsviewFunctionEnc;
import java.util.Map;
@JSViewPlugin(
// 插件名称
pluginName = "我的插件",
// 插件版本名
versionName = "1.0",
// 插件版本号
versionCode = 1,
// 插件包名,类似 apk 的包名,用于与其他插件区分。
packageName = "com.abc.myplugin"
)
public class MyJSViewPlugin extends JSViewPluginBase {
public MyJSViewPlugin(Map<String, Object> param, JsviewFunctionEnc funcEncRef, String pluginName) {
super(param, funcEncRef, pluginName);
}
// TODO 添加自己的接口
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 添加给 js 调用的接口
在MyJSViewPlugin.java
创建自己的方法,用@JavascriptInterface
注解,
参数和返回值类型只支持基本数据类型。
@JavascriptInterface
public void testFunction(String text){
Log.d("MyPlugin", "testFunction: "+text);
}
2
3
4
# 编译插件
点击编译项目后就会得到两个文件:
./MyPlugin/app/build/generated/ap_generated_sources/debug/out/js/MyJSViewPlugin.js
./MyPlugin/app/build/outputs/apk/release/app-release-unsigned.apk
# 使用插件
- 将 apk 文件部署到 http 服务器上。
- 修改
MyJSViewPlugin.js
文件里的 apk 文件下载地址跟apk 文件 md5.
let PluginInfo={
//插件下载地址
downloadUrl:"http://192.168.2.179:8092/app/build/outputs/apk/release/app-release-unsigned.apk",
// apk 文件的md5
md5:"e7c9ef87c1bd283c2ab4be10852e2358",
packageName:"com.abc.myplugin", // 插件包名
name:"我的插件", // 插件名
version:"1.0", //插件需要的版本号
versionCodeMin:1,
versionCodeMax:1,
bridgeName:"jPMyJSViewPlugin", //插件bridge注册到jsview的名称
className:"com.sample.myplugin.MyJSViewPluginCreator", //插件初始化类名称
initMethod:"createInstance", //插件初始化方法
listener:"__MyJSViewPluginPluginLoadResult", //插件加载结果回调
listener2: "__MyJSViewPluginPluginStatus",
};
...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
注意: $\color{red}{正式上线一般不需要配置下载地址和md5}$ ,插件会根据包名和版本自动去对应后台下载。具体插件管理后台联系相关人员。
- 小程序集成
MyJSViewPlugin.js
把MyJSViewPlugin.js
放到自己的小程序项目中并引用。
import { MyJSViewPlugin } from "./MyJSViewPlugin";
- 加载插件
// 调用globalLoadPlugin接口加载插件
MyJSViewPlugin.globalLoadPlugin((obj)=>{
/**
* 插件加载状态回调。
* 回调函数的参数定义如下:
* object结构,包含status和code两个变量:
* 1)开始加载插件:
* obj.status=1;
* obj.code表示是否是首次加载:1:首次加载,此时插件需要经历下载、解压等过程,用时较长,可以考虑给用户相关提示;
* 2:非首次加载,此时插件加载过程很短,可以不用出现用户提示界面。
* 2)插件加载中,加载新插件时上报此状态完整状态,加载旧插件时,只上报dexload完成状态(code=3):
* obj.status=2;
* obj.code表示加载过程中的状态:1:插件下载进度,目前只上报下载结束;2:插件解压完成;3:插件dexload完成。
* obj.progress:当code=1时(下载进度),progress为实际下载进度,百分制,目前只有100(100%,完成状态)。
* 3)插件加载成功
* obj.status=3;
* obj.code无效。
* 4)插件加载失败
* obj.status=4;
* obj.code表示插件加载失败原因:1:插件管理模块不存在(未真正开始加载插件),下面的负值为插件管理模块返回的错误;
* -1:请求插件加载的参数不正确,需要确认构造的PluginInfo内容;
* -2:未找到插件更新链接;
* -3:插件HTTP请求失败;
* -4:插件下载失败;
* -5:插件MD5校验失败;
* -6:解压失败;
* -7:文件大小为0;
* -8:未找到dex文件;
* -9:dex文件load失败;
* -10:插件初始化失败;
* -11:取消插件下载;
* -12:版本检查失败,比如已经加载了其他版本,此版本不能再加载。
*
*/
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
- 调用插件接口
// 插件加载成功后可以调用 java 中定义好的接口
MyJSViewPlugin.testFunction("来自javascript的调用!")
2
# Android 如何调用 js 的方法
如果 java 部分有些事件发生想通知到 js 可以在插件的 java 代码里添加一个方法然后用@JavascriptFunction
注解:
/**
* 调用此方法会通知到 js 层
* 方法名不限制,但返回值和参数只支持基本数据类型,
* 方法里不要写逻辑
*/
@JavascriptFunction
public String javaEvent(int event){
return null;
}
2
3
4
5
6
7
8
9
10
在 js 代码中实现这个方法:
// 注意:方法名要跟 java 一样,参数数量也要对应上
MyJSViewPlugin.nativeCallback.javaEvent = (event)=>{
console.log("来自 java 的调用:"+event)
return "这是来自 js 的字符串";
}
2
3
4
5
最后在 java 中调用javaEvent
接口即可:
String str = javaEvent(123);
# 插件管理模块功能
JsviewFunctionEnc.java 封装了所有插件管理模块支持的功能
/******************************************************************************
* 本文件封装了插件管理模块支持的接口。使用者调用前需要先初始化,把插件管理模块初始化插件时
* 传入的参数传给构造函数。
******************************************************************************/
package com.qcode.jsvplayer;
import android.os.Bundle;
import android.util.Log;
import android.widget.FrameLayout;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
public class JsviewFunctionEnc {
private String TAG = "JsviewFunctionEnc";
private Map mParam;
public interface HoleStyleChangeListener {
void onEvent(Bundle data);
}
public interface NetStateChangeListener {
void onEvent(int status);
}
JsviewFunctionEnc(Map param){
mParam = param;
}
/***************************************
* 注册js interface
* @param bridge js interface对象
* @return {int} 0表示成功,-1表示失败
***************************************/
public int addJsvBridge(Object bridge){
if(mParam.containsKey("jsView") && mParam.containsKey("bridgeName") && mParam.containsKey("addJsvBridge")) {
String bridge_name = (String) mParam.get("bridgeName");
Method add_bridge = (Method) mParam.get("addJsvBridge");
Object js_view = (Object) mParam.get("jsView");
try {
add_bridge.setAccessible(true);//调用方法前,设置访问标志
add_bridge.invoke(js_view, bridge_name, bridge);//使用方法
return 0;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Add bridge failed, no enough params!");
}
return -1;
}
/*********************************************
* 发送事件给js端
* @param key {string} 事件名称
* @param value {string} json string,事件值
* @return {int} 0表示成功,-1表示失败
*********************************************/
public int emitEvent(String key, String value){
if(mParam!=null && mParam.containsKey("jsView") && mParam.containsKey("emitEvent")) {
Method emit_event = (Method) mParam.get("emitEvent");
Object js_view = (Object) mParam.get("jsView");
try {
emit_event.setAccessible(true);
emit_event.invoke(js_view, key, value);
return 0;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Send event failed, no enough params!");
}
return -1;
}
/*************************************************
* 调用js回调函数
* @param callback {string} js注册下来的回调函数名称
* @param value {string} json string,回调函数参数
* @return {int} 0表示成功,-1表示失败
*************************************************/
public int evaluateJsFunction(String callback, String value){
if(mParam!=null && mParam.containsKey("jsView") && mParam.containsKey("evaluateJsFunction")) {
Method evaluateJsFunction = (Method) mParam.get("evaluateJsFunction");
Object js_view = (Object) mParam.get("jsView");
try {
evaluateJsFunction.setAccessible(true);
evaluateJsFunction.invoke(js_view, callback, value);
return 0;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Send callback failed, no enough params!");
}
return -1;
}
/*********************************************************************
* 获取jsview(小程序所有在view)的back view,插件支持back view和front view,
* 其中back view在jsview后面,需要给jsview打个洞,才可以透出来,一般用于播放
* 器插件等场景,front view在jsview前面,直接盖在jsview上面。
* @return {FrameLayout} back view对象
*********************************************************************/
public FrameLayout getBackgroundRootView(){
if(mParam.containsKey("jsView") && mParam.containsKey("getRootView")) {
Method get_rootview = (Method) mParam.get("getRootView");
Object js_view = (Object) mParam.get("jsView");
try {
get_rootview.setAccessible(true);
return (FrameLayout) get_rootview.invoke(js_view, true);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Get background root view failed, no enough params!");
}
return null;
}
/*********************************************************************
* 获取jsview(小程序所有在view)的front view,插件支持back view和front view,
* 其中back view在jsview后面,需要给jsview打个洞,才可以透出来,一般用于播放
* 器插件等场景,front view在jsview前面,直接盖在jsview上面。
* @return {FrameLayout} front view对象
*********************************************************************/
public FrameLayout getFrontRootView(){
if(mParam.containsKey("jsView") && mParam.containsKey("getRootView")) {
Method get_rootview = (Method) mParam.get("getRootView");
Object js_view = (Object) mParam.get("jsView");
try {
get_rootview.setAccessible(true);
return (FrameLayout) get_rootview.invoke(js_view, false);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Get front root view failed, no enough params!");
}
return null;
}
/*************************************
* 通知jsview释放焦点,用于back view或者
* front view需要焦点的场景
*************************************/
public void releaseFocus(){
if(mParam.containsKey("jsView") && mParam.containsKey("releaseFocus")) {
Method release_focus = (Method) mParam.get("releaseFocus");
Object js_view = (Object) mParam.get("jsView");
try {
release_focus.setAccessible(true);
release_focus.invoke(js_view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Release focus failed, no enough params!");
}
}
/***********************************************
* 监听在jsview上打的洞的状态变化,主要是尺寸的变化
* @param track_id {string} 打的洞的索引
* @param listener 回调函数
* @return {int} 0表示成功,-1表示失败
***********************************************/
public int registerHoleStyleChange(String track_id, HoleStyleChangeListener listener){
if(mParam.containsKey("jsView") && mParam.containsKey("registerHoleStyleChange")) {
Method register_hole_style_change = (Method) mParam.get("registerHoleStyleChange");
Object js_view = (Object) mParam.get("jsView");
try {
register_hole_style_change.setAccessible(true);
try {
register_hole_style_change.invoke(js_view, track_id, listener.getClass().getMethod("onEvent", Bundle.class), listener);
return 0;
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Register hole style change failed, no enough params!");
}
return -1;
}
/**************************************
* 取消对所打的洞的变化的监听
* @param track_id {string} 打的洞的索引
* @return {int} 0表示成功,-1表示失败
**************************************/
public int unregisterHoleStyleChange(String track_id){
if(mParam.containsKey("jsView") && mParam.containsKey("unregisterHoleStyleChange")) {
Method unregister_hole_style_change = (Method) mParam.get("unregisterHoleStyleChange");
Object js_view = (Object) mParam.get("jsView");
try {
unregister_hole_style_change.setAccessible(true);
unregister_hole_style_change.invoke(js_view, track_id);
return 0;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Unregister hole style change failed, no enough params!");
}
return -1;
}
/*****************************************
* 注册网络状态变化监听
* @param name {string} key,用于注销时传入
* @param listener 回调函数
* @return {int} 0表示成功,-1表示失败
*****************************************/
public int registerNetStateChange(String name, NetStateChangeListener listener){
if(mParam.containsKey("jsView") && mParam.containsKey("registerNetStateChange")) {
Method register_net_state_change = (Method) mParam.get("registerNetStateChange");
Object js_view = (Object) mParam.get("jsView");
try {
register_net_state_change.setAccessible(true);
try {
register_net_state_change.invoke(js_view, name, listener.getClass().getMethod("onEvent", Integer.class), listener);
return 0;
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Register net state change failed, no enough params!");
}
return -1;
}
/**********************************************
* 注销网络状态变化监听
* @param name {string }key,使用注册时传入的值
* @return {int} 0表示成功,-1表示失败
**********************************************/
public int unregisterNetStateChange(String name){
if(mParam.containsKey("jsView") && mParam.containsKey("unregisterNetStateChange")) {
Method unregister_net_state_change = (Method) mParam.get("unregisterNetStateChange");
Object js_view = (Object) mParam.get("jsView");
try {
unregister_net_state_change.setAccessible(true);
unregister_net_state_change.invoke(js_view, name);
return 0;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Unregister net state change failed, no enough params!");
}
return -1;
}
/*********************************
* 获取电视小程序渠道号
* @return {string} 渠道号
*********************************/
public String getMarketCode(){
if(mParam.containsKey("jsView") && mParam.containsKey("getMarketCode")) {
Method get_market_code = (Method) mParam.get("getMarketCode");
Object js_view = (Object) mParam.get("jsView");
try {
get_market_code.setAccessible(true);
return (String)get_market_code.invoke(js_view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Get market code failed, no enough params!");
}
return null;
}
/*****************************************
* 获取电视小程序唯一标识,uuid
* @return {string} uuid
*****************************************/
public String getUUID(){
if(mParam.containsKey("jsView") && mParam.containsKey("getUUID")) {
Method get_uuid = (Method) mParam.get("getUUID");
Object js_view = (Object) mParam.get("jsView");
try {
get_uuid.setAccessible(true);
return (String)get_uuid.invoke(js_view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Get uuid failed, no enough params!");
}
return null;
}
/***************************
* 获取以太网mac地址
* @return {string} mac地址
***************************/
public String getEthMac(){
if(mParam.containsKey("jsView") && mParam.containsKey("getEthMac")) {
Method get_eth_mac = (Method) mParam.get("getEthMac");
Object js_view = (Object) mParam.get("jsView");
try {
get_eth_mac.setAccessible(true);
return (String)get_eth_mac.invoke(js_view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Get ethernet mac failed, no enough params!");
}
return null;
}
/******************************
* 获取wifi mac地址
* @return {string} mac地址
******************************/
public String getWifiMac(){
if(mParam.containsKey("jsView") && mParam.containsKey("getWifiMac")) {
Method get_wifi_mac = (Method) mParam.get("getWifiMac");
Object js_view = (Object) mParam.get("jsView");
try {
get_wifi_mac.setAccessible(true);
return (String)get_wifi_mac.invoke(js_view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Get wifi mac failed, no enough params!");
}
return null;
}
/*********************************************************
* 获取调用小程序的信息,值为小程序的appname+"|"+小程序链接的md5;
* 主要用于识别加载插件的小程序的信息。
* @return {string} refeffer,加载者信息
*********************************************************/
public String getReferrer(){
if(mParam.containsKey("jsView") && mParam.containsKey("getReferrer")) {
Method get_referrer = (Method) mParam.get("getReferrer");
Object js_view = (Object) mParam.get("jsView");
try {
get_referrer.setAccessible(true);
return (String)get_referrer.invoke(js_view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Get referrer failed, no enough params!");
}
return null;
}
/**********************************************
* 校验小程序签名
* @param signKey {string} 支持的小程序签名
* @return {boolean} true表示通过,false表示失败
**********************************************/
public boolean checkSignKey(String signKey){
if(mParam.containsKey("jsView") && mParam.containsKey("checkSignKey")) {
Method check_sign_key = (Method) mParam.get("checkSignKey");
Object js_view = (Object) mParam.get("jsView");
try {
check_sign_key.setAccessible(true);
return (boolean)check_sign_key.invoke(js_view, signKey);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
Log.d(TAG, "Unregister net state change failed, no enough params!");
}
return false;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
支持的接口如下
# addJsvBridge
注册js interface,插件模块将js interface接口进行注册,以便js端可以正确访问插件提供的js穿透接口。
# emitEvent
插件发送事件给js端,一般用于状态的通报。
# evaluateJsFunction
调用插件js端注册的回调函数,一般用于异步调用完成后的结果通知。
# getBackgroundRootView
插件管理模块给插件提供了back view和front view,其中back view显示在jsview(加载小程序的view)后面,front view显示在jsview的前面。插件如果需要进行界面展示,可以根据不同场景需求,选择对应的view。
本接口获取back view
# getFrontRootView
获取front view
# releaseFocus
如果back view或者front view需要获取焦点,通知jsview失去焦点。
# registerHoleStyleChange
对于back view,需要在jsview上打洞,back view才可见,本接口用于通知洞的状态变化。
# unregisterHoleStyleChange
注销jsview洞的状态变化通知函数。
# registerNetStateChange
注册网络状态变化通知接口。
# unregisterNetStateChange
注销网络状态变化通知接口。
# getMarketCode
获取电视小程序apk的渠道号。
# getUUID
获取终端唯一标识。
# getEthMac
获取终端以太网(有线)mac地址。
# getWifiMac
获取终端wifi mac(无线mac)地址。
# getReferrer
获取加载插件的小程序信息,值为小程序的appname+"|"+小程序链接(url)的md5。
# checkSignKey
校验小程序签名。