递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库
查看: 3918|回复: 12
打印 上一主题 下一主题

[安卓] 如何让JS脚本执行完可获取返回值

[复制链接]

1

主题

19

帖子

82

积分

注册会员

Rank: 2

积分
82
跳转到指定楼层
楼主
发表于 2023-10-23 22:35:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
论坛找的JS脚本类..  调用后是用执行完毕得到的结果..  但是..每次在主线程的时候,都获取不到内容...  应该是JS内容还没有执行完
想了各种办法 仍然无法达到要求...  怎么样能等待JS执行完毕再继续执行下边的代码
  1. <火山程序 类型 = "通常" 版本 = 1 />

  2. 包 火山.样例 <注释 = "火山无名模块:">

  3. 类 启动类 <公开 基础类 = 安卓5无标题白色窗口 注释 = "用户主窗口封装类." 注释 = "此处设置了常用的附加清单属性,如果不需要可删除." @安卓.附加清单 = 常用窗口附加清单.全面屏
  4.         @安卓.附加清单 = 常用附加清单.开启硬件加速 @安卓.附加清单 = 常用窗口附加清单.不改变软键盘状态>
  5. {
  6.     变量 按钮_解析JSON <类型 = 按钮 隐藏值属性 = "0" @安卓.窗口.布局 = "p_layout_horz_align = left" 内容 = "利用js解析JSON">
  7.     变量 编辑框_路径 <类型 = 编辑框 隐藏值属性 = "0"
  8.             @安卓.窗口.布局 = "ctrl_order = 1\np_layout_height_type = wrap_content\np_layout_width_type = match_parent"
  9.             内容 = "user.address[0].postcode" 单行模式 = 真>
  10.     变量 编辑框_json <类型 = 编辑框 隐藏值属性 = "0"
  11.             @安卓.窗口.布局 = "ctrl_order = 2\np_layout_height_type = p_specified\np_layout_height_value = 50\np_layout_width_type = match_parent"
  12.             内容 = "{ "username":"andy", "age":20, \n"info": { "tel": "123456", "cellphone": "98765"}, \n"address": [ {"city":"beijing","postcode":"222333"}, \n{"city":"newyork","postcode":"火山"} ] }">
  13.     变量 按钮_载入并执行 <类型 = 按钮 隐藏值属性 = "0" @安卓.窗口.布局 = "ctrl_order = 3" 内容 = "载入js并执行">
  14.     变量 脚本 <类型 = JS脚本类>

  15.     方法 通知_被创建 <公开 注释 = "火山无名模块:" @虚拟方法 = 可覆盖>
  16.     参数 启动信息对象 <类型 = 启动信息类>
  17.     参数 载入参数 <类型 = "对象类 []">
  18.     参数 参数数目 <类型 = 整数>
  19.     {
  20.         父对象.通知_被创建 (启动信息对象, 载入参数, 参数数目)
  21.         脚本.初始化 (本对象)  // 必须初始化后才能调用
  22.     }

  23.     方法 按钮_被单击 <接收事件 类型 = 整数>
  24.     参数 来源对象 <类型 = 按钮 注释 = "提供事件产生的具体来源对象" 编辑时信息 = "42AA6, 0, 0, 0">
  25.     参数 标记值 <类型 = 整数 注释 = "用户调用"挂接事件"命令时所提供的"标记值"参数值,非此方式挂接事件则本参数值固定为0." 编辑时信息 = "42AA6, 0, 0, 0">
  26.     {
  27.         如果 (来源对象 == 按钮_载入并执行)
  28.         {
  29.             常量 JS代码 <类型 = 文本型
  30.                     值 = "function Add(x, y) {\n    return x+y;\n  }\n  function Add2(x, y) {\n    return x+y;\n  }\n  function Add3() {\n    return "火山";\n  }">
  31.             脚本.载入JS (JS代码, 1)
  32.             提示信息框 ("JSON返回结果:" + 全局变量.token)
  33.             // 这里全局变量怎么都不能及时的获取..  试验了各种办法
  34.             //怎么样能等待JS执行完毕返回了变量  再继续进行下边的代码

  35.         }
  36.         否则 (来源对象 == 按钮_解析JSON)
  37.         {
  38.             //JSON解析 (编辑框_json.内容, 编辑框_路径.内容)
  39.             //提示信息框 ("JSON返回结果:" + 全局变量.token)
  40.         }
  41.         返回 (0)
  42.     }

  43.     方法 JSON解析
  44.     参数 JSON文本 <类型 = 文本型>
  45.     参数 JSON路径 <类型 = 文本型>
  46.     {
  47.         变量 脚本1 <类型 = 文本型 值 = "var user = @<内容1>;\nreturn @<内容2>;">
  48.         脚本1 = 子文本替换 (脚本1, "@<内容1>", JSON文本)
  49.         脚本1 = 子文本替换 (脚本1, "@<内容2>", JSON路径)
  50.         脚本.执行JS (脚本1, 1)
  51.     }

  52.     方法 JS脚本类_执行完毕 <接收事件 类型 = 整数>
  53.     参数 来源对象 <类型 = JS脚本类>
  54.     参数 标记值 <类型 = 整数>
  55.     参数 所返回数据 <类型 = 文本型>
  56.     参数 标记 <类型 = 整数>
  57.     {
  58.         如果 (来源对象 == 脚本)
  59.         {
  60.             如果 (所返回数据 == "null")
  61.             {
  62.                 提示框 ("无返回数据")
  63.                 返回 (0)
  64.             }
  65.             如果 (标记 == 1)  // 判断是否为JSON解析
  66.             {
  67.                 全局变量.token = 所返回数据
  68.                 // 提示信息框 ("JSON返回结果:" + 所返回数据)
  69.             }
  70.             否则 (标记 == 2)
  71.             {
  72.                 全局变量.token = 所返回数据

  73.                 // 提示框 ("执行JS方法结果:" + 所返回数据)
  74.             }
  75.         }
  76.         返回 (0)
  77.     }

  78.     方法 JS脚本类_载入JS完毕 <接收事件 类型 = 整数 折叠>
  79.     参数 来源对象 <类型 = JS脚本类>
  80.     参数 标记值 <类型 = 整数>
  81.     参数 标记 <类型 = 整数>
  82.     {
  83.         如果 (标记 == 1)  // 判断载入来源
  84.         {
  85.             脚本.执行JS方法 ("Add(1,2)", 2)  // 可以执行载入js中的各种写好的方法
  86.             脚本.执行JS方法 ("Add2(2,2)", 2)
  87.             脚本.执行JS方法 ("Add3()", 2)
  88.             来源对象.释放载入 ()  // 释放后将不能调用载入的方法.
  89.         }
  90.         返回 (0)
  91.     }
  92. }

  93. 类 JS脚本类 <公开 注释 = "火山无名模块:" 注释 = "用于执行加载JavaScript脚本">
  94. {
  95.     变量 浏览框1 <参考 类型 = 浏览框>
  96.     变量 成员执行的方法 <类型 = 文本型>

  97.     方法 初始化 <公开 注释 = "初始化当前对象,必须初始化后才能使用." 折叠>
  98.     参数 所处窗口 <类型 = 安卓窗口>
  99.     {
  100.         浏览框1 = 所处窗口.创建窗口组件 (浏览框)
  101.         挂接事件 (浏览框1)
  102.     }

  103.     方法 载入JS <公开 注释 = "准备一段JavaScript代码,载入到当前对象中,载入后可调用"执行JS方法"执行js中的各种方法." 注释 = "载入完毕后将触发"载入JS完毕"事件."
  104.             折叠>
  105.     参数 脚本内容 <类型 = 文本型 注释 = "提供完整的JavaScript代码">
  106.     参数 标记 <类型 = 整数 注释 = "设置载入标记,当载入完毕后可通过"载入JS完毕"事件的标记参数获取." "">
  107.     {
  108.         如果 (浏览框1 != 空对象)
  109.         {
  110.             浏览框1.标记 = 到文本 (标记)
  111.             变量 脚本1 <类型 = 文本型 值 = "<html><body><script>脚本</script></body></html>">
  112.             浏览框1.载入数据 (子文本替换 (脚本1, "脚本", 脚本内容), "text/html; charset=UTF-8")
  113.         }
  114.     }

  115.     方法 释放载入 <公开 注释 = "释放"载入JS"方法载入的js代码,释放后将不能执行其中的任何方法.">
  116.     {
  117.         如果 (浏览框1 != 空对象)
  118.         {
  119.             浏览框1.载入数据 ("")
  120.         }
  121.     }

  122.     方法 执行JS方法 <公开 注释 = "当调用了"载入JS"方法后可调用本方法执行其中的js方法." 注释 = "注意:本方法只能在"载入JS完毕"事件下才能调用.">
  123.     参数 要执行的方法 <类型 = 文本型 注释 = "提供js方法名,例如:getValue()">
  124.     参数 标记 <类型 = 整数 注释 = "当执行多个脚本时,可用于在事件中判断执行来源.">
  125.     {
  126.         如果 (浏览框1 != 空对象)
  127.         {
  128.             浏览框1.标记 = 到文本 (标记)
  129.             浏览框1.执行JS方法2 (要执行的方法)
  130.         }
  131.     }

  132.     方法 执行JS <公开 注释 = "直接执行一段JavaScript代码,本方法将触发"执行完毕"事件." 注释 = "注意:本方法并不能执行"载入JS"方法载入的js内容."
  133.             编辑时信息 = "2FFFD, 0, 0, 0">
  134.     参数 脚本内容 <类型 = 文本型 注释 = "提供JavaScript代码,譬如:return 1+1;" 编辑时信息 = "2FFFD, 0, 0, 0">
  135.     参数 标记 <类型 = 整数 注释 = "当执行多个脚本时,可用于在事件中判断执行来源." 编辑时信息 = "2FFFD, 0, 0, 0">
  136.     {
  137.         如果 (浏览框1 != 空对象)
  138.         {
  139.             浏览框1.标记 = 到文本 (标记)
  140.             浏览框1.执行JS方法2 ("(function() {" + 脚本内容 + "})();")
  141.         }
  142.     }

  143.     方法 执行完毕 <公开 定义事件 类型 = 整数 注释 = "执行JavaScript完毕后触发本事件." 折叠>
  144.     参数 所返回数据 <类型 = 文本型 注释 = "返回执行结果,无数据返回null.">
  145.     参数 标记 <类型 = 整数 注释 = "返回标记值">

  146.     方法 载入JS完毕 <公开 定义事件 类型 = 整数 注释 = "调用了"载入JS"方法后本事件将被触发." 注释 = "触发后可调用"执行JS方法"执行其中的各种JS方法.">
  147.     参数 标记 <类型 = 整数 注释 = "返回载入JS方法提供的标记值">

  148.     方法 浏览框_JS返回数据 <接收事件 类型 = 整数>
  149.     参数 来源对象 <类型 = 浏览框>
  150.     参数 标记值 <类型 = 整数>
  151.     参数 所返回数据 <类型 = 文本型>
  152.     {
  153.         执行完毕 (所返回数据, 文本到整数 (来源对象.标记))
  154.         返回 (0)
  155.     }

  156.     方法 浏览框_页面载入完毕 <接收事件 类型 = 整数>
  157.     参数 来源对象 <类型 = 浏览框>
  158.     参数 标记值 <类型 = 整数>
  159.     参数 页面地址 <类型 = 文本型>
  160.     {
  161.         载入JS完毕 (文本到整数 (来源对象.标记))
  162.         返回 (0)




  163.     }
  164. }

  165. 类 全局变量 <公开>
  166. {
  167.     变量 token <公开 静态 类型 = 文本型>

  168.     #
  169. }
复制代码




回复

使用道具 举报

1

主题

19

帖子

82

积分

注册会员

Rank: 2

积分
82
沙发
 楼主| 发表于 2023-10-23 22:38:37 | 只看该作者
一个人默默学习...  资料太少..  真的无可奈何了...   早上到晚上...  还是解决不了...
回复

使用道具 举报

1

主题

19

帖子

82

积分

注册会员

Rank: 2

积分
82
板凳
 楼主| 发表于 2023-10-23 23:36:36 | 只看该作者
本帖最后由 悲伤何须逆流 于 2023-10-23 23:37 编辑

补充..  如果在 JS脚本类_执行完毕 中 安卓网络操作类.HTTP读文件2 运行所需要访问网页...  无法正常访问  直接带入固定cook  在按钮点击运行下一切正常...
并且在 JS脚本类_执行完毕 中取cookies会报错...  安卓网络操作类.Cookies键值对象.Cookies
所以才想获取返回值  在按钮下代入cookies执行...  就会一切正常了吧...
我还怀疑 是因为创建了JS类创建了浏览框导致的...所以在JS脚本类_执行完毕中数据不正常..  例如协议头无法统一之类...

错误: java.lang.NullPointerException: Attempt to read from field 'java.lang.文本型 hsh.anzh.jb.网络请求数据类.Cookies' on a null object reference
<D:\huoshanmianfeibanben\xiangmu\百\src\main.v>, 286: 错误: 位于 com.bjlwzxz.lm.启动类.JS脚本类_执行完毕
<D:\huoshanmianfeibanben\xiangmu\百\src\main.v>, 19: 错误: 位于 com.bjlwzxz.lm.启动类$1.dispatch
<D:\huoshanmianfeibanben\xiangmu\百\src\main.v>, 436: 错误: 位于 com.bjlwzxz.lm.JS脚本类.执行完毕
<D:\huoshanmianfeibanben\xiangmu\百\src\main.v>, 445: 错误: 位于 com.bjlwzxz.lm.JS脚本类.浏览框_JS返回数据
<D:\huoshanmianfeibanben\xiangmu\百\src\main.v>, 413: 错误: 位于 com.bjlwzxz.lm.JS脚本类$1.dispatch
<D:\huoshanmianfeibanben\win_android_chs_free\plugins\vprj_android\classlib\sys\android\ctrl_webview\a_ctrl_webview.v>, 25: 错误: 位于 hsh.anzh.zj.llk.浏览框.JS返回数据
<D:\huoshanmianfeibanben\win_android_chs_free\plugins\vprj_android\classlib\sys\android\ctrl_webview\a_ctrl_webview.v>, 17: 错误: 位于 hsh.anzh.zj.llk.浏览框$5.onReceiveValue
<D:\huoshanmianfeibanben\win_android_chs_free\plugins\vprj_android\classlib\sys\android\ctrl_webview\a_ctrl_webview.v>, 17: 错误: 位于 hsh.anzh.zj.llk.浏览框$5.onReceiveValue
错误: 位于 SO.onResult(chromium-Monochrome.aab-stable-463807426:1)
错误: 位于 org.chromium.base.Callback.l(chromium-Monochrome.aab-stable-463807426:1)
错误: 位于 org.chromium.base.Callback.m(chromium-Monochrome.aab-stable-463807426)
错误: 位于 LO.run(chromium-Monochrome.aab-stable-463807426)
回复

使用道具 举报

23

主题

317

帖子

1471

积分

金牌会员

Rank: 6Rank: 6

积分
1471
地板
发表于 2023-10-23 23:37:16 | 只看该作者
本帖最后由 wangvoldp 于 2023-10-23 23:39 编辑

不好意思看错了, 还以为是视图的edge呢, 请忽略下面内容

执行js是异步的,所以不能马上得到结果, 如果想区分开每次调用的结果 有两种方法
1. 运行JS_异步 时传入用户数据, 在 JS执行完成 事件里判断这个用户数据,来确定是哪次调用的
2. 利用C++的lamdba函数, 执行js原始时起始也是回调的lamdba函数, 大致方法如下    新定义几个自己的函数, 通过加入和如果真一样的body来实现回调(此处代码不是最新的edge支持库代码,仅供参考)
----------------------------------------------------------------
<火山程序 类型 = "通常" 版本 = 1 />

方法 执行JS_嵌入 <公开
        @嵌入式方法 = "name = wv2_runjs\r\nhas_body = true\r\nbody_header = \"@none\"\r\nbody_tail = \"    return S_OK;\\n}).Get()\\n);\"">
参数 JS脚本 <类型 = 文本型>
{
    @ @sn<this>.m_webView2 -> ExecuteScript(
    @     @<JS脚本>.GetText(),
    @     Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
    @         [this](HRESULT errorCode, PCWSTR resultObjectAsJson) -> HRESULT {
}


方法 取执行结果 <公开 类型 = 文本型 @嵌入式方法 = "parent = wv2_runjs">
{
    @ CVolString(resultObjectAsJson)
}

方法 取执行错误代码 <公开 类型 = 整数 @嵌入式方法 = "parent = wv2_runjs">
{
    @ errorCode
}

----------------------------------------------------------------
浏览器.执行JS_嵌入("js的脚本内容")
| 调试输出(浏览器.取执行结果())
| 调试输出(浏览器.取执行错误代码())

上面方法【执行JS_嵌入】会和如果真一样多个缩进, 只要执行完毕 他就会执行缩进后面的代码,
这样我们就可以愉快的在各个地方 执行JS了, 需要结果的 可以使用【 取执行结果】,不用区分哪个是哪个了

评分

参与人数 1金钱 +3 收起 理由
悲伤何须逆流 + 3 感谢回答

查看全部评分

回复

使用道具 举报

1

主题

19

帖子

82

积分

注册会员

Rank: 2

积分
82
5#
 楼主| 发表于 2023-10-23 23:43:19 | 只看该作者
wangvoldp 发表于 2023-10-23 23:37
执行js是异步的,所以不能马上得到结果, 如果想区分开每次调用的结果 有两种方法
1. 运行JS_异步 时传入用户 ...

非常感谢   虽然没看太明白...  但我只能尝试第二个方式了..  因为第一个方式   在运行完JS后  循环判断变量是否获取值时  导致JS执行完成事件一直无法运行完成... 所以变量值一直不变... 无法确定是否调用成功...  并且在JS完成事件执行安卓操作类有问题...  
回复

使用道具 举报

1

主题

19

帖子

82

积分

注册会员

Rank: 2

积分
82
6#
 楼主| 发表于 2023-10-23 23:46:22 | 只看该作者
wangvoldp 发表于 2023-10-23 23:37
不好意思看错了, 还以为是视图的edge呢, 请忽略下面内容

执行js是异步的,所以不能马上得到结果, 如果想区 ...

我还在想可行性.....  你又改了回复...  我哭...
回复

使用道具 举报

23

主题

317

帖子

1471

积分

金牌会员

Rank: 6Rank: 6

积分
1471
7#
发表于 2023-10-23 23:47:33 | 只看该作者
悲伤何须逆流 发表于 2023-10-23 23:43
非常感谢   虽然没看太明白...  但我只能尝试第二个方式了..  因为第一个方式   在运行完JS后  循环判断 ...

亲 你不能执行js后,用循环来判断一个变量是否有结果, 比如登录按钮吧, 点下按钮, 禁用该按钮,执行js,在js完毕事件里判断是不是登录按钮的js, 是的话取消禁用登录按钮,根据登录结果执行登录后的动作, 第二种是c++的写法,安卓应该不支持,我也不确定不懂安卓
回复

使用道具 举报

1

主题

19

帖子

82

积分

注册会员

Rank: 2

积分
82
8#
 楼主| 发表于 2023-10-23 23:54:11 | 只看该作者
wangvoldp 发表于 2023-10-23 23:47
亲 你不能执行js后,用循环来判断一个变量是否有结果, 比如登录按钮吧, 点下按钮, 禁用该按钮,执行js,在js ...

好的吧 目前只能曲线救国了...  因为点了按钮执行子程序  想要获取cook  然后带入直接访问获取**..  现在这个情况 只能让客户多点一次按钮   或者在JS计算前  按钮改为禁止   执行完毕事件取消禁用按钮   JS代码后循环判断按钮是否被禁用执行**操作...  代码都改为主线程执行 应该是没什么问题...  目前只能这样测试了 两个方式  肯定有一个是可以的.. 不确定安卓有没有禁用 没有的话可以加入一个隐藏标签来进行判断...   还是感谢... 因为研究了一天  脑子有点僵化..  跟这个耗上了...  现在突然不纠结于必须要这样运行了...
回复

使用道具 举报

444

主题

1万

帖子

4万

积分

超级版主

Rank: 8Rank: 8

积分
40529
9#
发表于 2023-10-24 07:14:34 | 只看该作者
安卓没有封js执行库。。利用浏览器去执行js,其实不是那么好用的。
安卓无障碍实战课:点击查看
交流群:641526939
回复

使用道具 举报

1

主题

19

帖子

82

积分

注册会员

Rank: 2

积分
82
10#
 楼主| 发表于 2023-10-24 08:14:46 | 只看该作者
创世魂 发表于 2023-10-24 07:14
安卓没有封js执行库。。利用浏览器去执行js,其实不是那么好用的。

刚开始学,小白一个,也确实没找到JS库..  所以在论坛找到了可以执行的方式...   就是调用后..  再运行安卓操作类命令,有问题.   想取出来不在执行完毕下运行吧  还死活取不出来..   论坛各种资料太少了..  
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|递归火山软件开发平台 ( 鄂ICP备18029190号 )

GMT+8, 2024-11-24 03:34 , Processed in 0.091227 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表