小程序基础库与Android之间通信优化的可能

news2024/12/25 9:04:10

最近在学习graalvm,发现有一个graaljs项目,项目中介绍可以让java与JavaScript做数据转换,比如JavaScript中可以使用java的数据类型与结构。突然想到之前遇到的一个问题,小程序中开发的代码和基础库的部分代码都是j2v8来执行的,其中的数据通信是通过bridge去做的,其实就是把数据结构都转换为字符串,这样就存在问题,比如Android这边的网络请求、音视频帧数据、文件流对外都是通过java封装的对象,无法直接在JavaScript中使用,只能是通过转换为base64来做,而且一个buffer数据基本需要两次转换,sdk转一次,基础库转一次,比较消耗性能。

如果JavaScript和java之间的结构互通,那是不是就解决这个问题了,理论上来说如果js引擎是通过java编写的解释器去执行,那确实是可以这样的。

GraalJs

GraalJs核心代码如下:

BufferedReader br = null;
try {
    br = new BufferedReader(new FileReader("/Users/xxx/tmp/index.md"));
} catch (FileNotFoundException e) {
    throw new RuntimeException(e);
}
try (Context context = Context.newBuilder().allowAllAccess(true).build()) {
    Set<String> languages = context.getEngine().getLanguages().keySet();
    for (String id : languages) {
        context.initialize(id);
        if (id.equals("js")) {
            context.eval("js", "function main(data) { console.log(data.readLine()); }");
            Value funMain = context.getBindings("js").getMember("main");
            funMain.execute(br);
        }
    }
}

这里我们使用GraalVM的jdk是可以运行的,可以看到JavaScript中接收到的data其实是java的BufferedReader,执行之后就发现JavaScript中的data.readLine成功执行并打印了文件内容,WC,如果Android可以这样那就太强了。可惜,GraalJs必须使用GraalVM提供的jdk,也不好直接替换android中使用的jdk。。。
那有没有其他办法?对了,GraalVM是可以将java代码生成分享库的,比如.so,Android也正好可以加载so库。有没有可能这样搞。最终项目如下https://github.com/schizobulia/GraalJs-Android ,可以看到releases中tag为v0.0.8中有arrch64和armv7的so库
截屏2024-01-11 10.02.00.png
可惜拿到so库之后去Android中使用发现,这个so库不是ABI。麻了…
然后查了相关资料发现GraalVM目前也没有计划支持Android。

不过好在最后发现ChatGPT确实是个好东西,现在查资料基本都是先问问ChatGPT,上面项目中的GitHub Action配置文件也是ChatGPT写的。

参考资料:
Android 关于CPU类型的so文件兼容问题(ABI) - 掘金
一分钟搞明白Android的.so文件、ABI和CPU的关系-CSDN博客

J2V8

那有没有可能从j2v8入手,比如node很多内置函数其实在v8中也是没有的,如果可以在v8中实现这些函数然后提供给JavaScript调用好像有可以,然后开始查node这部分功能的实现原理,最后看到一篇博客:Node.js的底层原理 - 掘金其中说到这个部分的实现是V8的自定义拓展实现的,好像确实可以。不过后来试了试,发现还是不行。

主要原因有:比如文件流、帧数据在Android端对外都是通过java封装的对象,v8的自定义扩展需要c++或者v8提供的语言来编写,依然存在语言之间数据结构转换的问题。

次要原因:实在不想看c++的代码

Rhino

然后通过ChatGPT最终选择试试Rhino,因为他也是java写的,缺点是性能可能没没v8那么强,JavaScript中新的语法糖或者全局属性可能没那么快支持到(不过可以使用一些打包库和第三方静态分析库去优化)。
小程序中存在大量的数据交互,如果使用Rhino说不定会有更好的效果,以下为示例代码,可以看到JavaScript中可以使用java的数据结构,这得益于解释器是使用java写的,节省了不同语言之间数据结构的转换。

var System = java.lang.System;
System.out.println(myClass.add(1, 2));
function test(str) {
    myClass.show(str);
}

通过下面代码的测试,发现读取一个53kb的文件从调用test方法到show方法的触发基本没消耗时间。而且根据这种方式其实也很节省内存,因为数据其实只保存在了jvm中,按j2v8的思路同一份数据需要在v8、jvm中各保存一份。
以下为完整代码:

package com.example.myapplication

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.myapplication.ui.theme.MyApplicationTheme
import org.mozilla.javascript.Context
import org.mozilla.javascript.Function
import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject
import java.nio.ByteBuffer
import java.nio.CharBuffer
import java.nio.charset.Charset


class MainActivity : ComponentActivity() {
    class MyFunctions {
        fun add(a: Int, b: Int): Int {
            return a + b
        }

        fun show(buffer: ByteArray) {
            println("这是js传递过来的:")
            println(System.currentTimeMillis())
            println(buffer)
//            val text = String(buffer)
//            println("File Content: $text")
        }
    }
    class JsEngine {
        public val rhino: Context = Context.enter()
        public val scope: Scriptable

        init {
            rhino.optimizationLevel = -1
            scope = rhino.initStandardObjects()

        }

        fun evaluate(jsCode: String) {
            try {
                ScriptableObject.putProperty(scope,"myClass", Context.javaToJS(MyFunctions(), scope))
                ScriptableObject.putProperty(scope, "javaContext", Context.javaToJS(this, scope))
                ScriptableObject.putProperty(scope, "javaLoader", Context.javaToJS(JsEngine::class.java.classLoader, scope))
                rhino.evaluateString(scope, jsCode, JsEngine::class.java.simpleName, 1, null)
            } finally {
//                Context.exit()
            }
        }

        fun callFunction(functionName: String, vararg args: Any): Any? {
            try {
                val function = scope[functionName, scope] as Function
                return function.call(rhino, scope, scope, args)
            } finally {
//                Context.exit()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
                    Greeting("Android")
                }
            }
        }

        val inputStream = resources.assets.open("data.txt");
        val size = inputStream.available()
        val buffer = ByteArray(size)
        inputStream.read(buffer)
        inputStream.close()
        Thread {
            val jsCode = """
            var System = java.lang.System;
            System.out.println(myClass.add(1, 2));
            function test(str) {
                myClass.show(str);
            }
                """.trimIndent()
            val jsEngine = JsEngine()
            jsEngine.evaluate(jsCode)
            println(System.currentTimeMillis())
            jsEngine.callFunction("test", buffer)
        }.start()
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
            text = "Hello $name!",
            modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    MyApplicationTheme {
        Greeting("Android")
    }
}

最后:ChatGPT真👍🏻

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1375747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

易安联参与制定的《面向云计算的零信任体系》行业标准即将实施

中华人民共和国工业和信息化部公告2023年第38号文件正式发布行业标准&#xff1a;YD/T 4598.2-2023《面向云计算的零信任体系 第2部分&#xff1a;关键能力要求》及YD/T 4598.3-2023《面向云计算的零信任体系 第3部分&#xff1a;安全访问服务边缘能力要求》&#xff0c;并于20…

如何将ArcGIS工程文件迁移到ArcGIS Pro内

当你刚接触ArcGIS Pro的时候&#xff0c;尝试新建一个工程文件会发现工程文件的后缀已经改变&#xff0c;那么以前在ArcGIS内辛苦制作的工程文件是否就不能在ArcGIS Pro内使用了&#xff0c;答案是否定的&#xff0c;对此Esri也给出了解决方案&#xff0c;这里为大家介绍一下迁…

数字化校园实验室综合管理平台|推动实验室创新发展新引擎

一、数字化建设目标 实验室数字化指的是运用新一代的人工智能、大数据、互联网技术、物联网技术、云计算技术、人体感应技术、语音技术、生物识别技术、手机APP等技术&#xff0c;实现各个业务间数据流和任务流的互通互联&#xff0c;将实验室管理过程中涉及的对象&#xff0c…

vue2 el-table行悬停时弹出提示信息el-popover

实现方法&#xff0c;用到了cell-mouse-enter、cell-mouse-leave两个事件&#xff0c;然后在表格的首列字段中&#xff0c;加个el-popover组件&#xff0c;当然你也可以选择在其他字段的位置来显示提示框&#xff0c;看自己的需求了。 示例代码&#xff1a; <el-table cell…

GLES学习笔记---立方体贴图(一张图)

一、首先看一张效果图 立方体贴图 二、纹理坐标划分 如上图是一张2D纹理&#xff0c;我们需要将这个2D纹理贴到立方体上&#xff0c;立方体有6个面&#xff0c;所以上面的2D图分成了6个面&#xff0c;共有14个纹理坐标 三、立方体 上边的立方体一共8个顶点坐标&#xff0c;范围…

Web3社交治理:用户参与决策的新模式

Web3时代的到来不仅仅带来了区块链技术的创新&#xff0c;还为社交治理带来了全新的模式。传统社交平台上的决策权通常集中在平台的运营方&#xff0c;而Web3社交治理的兴起意味着用户能够更直接地参与到社交平台的决策过程中。本文将深入探讨Web3社交治理的背景、工作原理以及…

9.云原生存储之ceph在k8s中应用及问题处理

文章目录 ceph应用场景ceph应用在k8s集群外使用块设备ceph客户端配置创建块挂载使用删除pool 在k8s集群内使用块设备创建块池和StorageClass使用存储 块存储映射问题处理问题现象事件分析csi-rbdplugin pod日志分析问题小结CentOS 7 编译安装 nbd 模块nbd内核模块介绍安装 nbd …

1.5计算机网络的分类

1.5计算机网络的分类 1.5.1按照网络的作用范围进行分类 1、广域网WAN 广域网WAN&#xff08;WideAreaNetwork&#xff09;&#xff1a;广域网的作用范围通常为几十到几千公里&#xff0c;因而有时也称为远程网(longhaulnetwork)。广域网是互联网的核心部分&#xff0c;其任务…

Linux单主机模拟测试docker macvlan网络

在单台宿主机上使用Linux Bridge&#xff0c;桥接不同网络命名空间&#xff08;namespace&#xff09;的方式&#xff0c;模拟测试docker macvlan网络&#xff0c;记录如下&#xff1a; 参考 链接: Macvlan network driver链接: Docker 网络模型之 macvlan 详解&#xff0c;图…

基于JavaWeb+BS架构+SpringBoot+Vue“共享书角”图书借还管理系统系统的设计和实现

基于JavaWebBS架构SpringBootVue“共享书角”图书借还管理系统系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 第1章 概 述 5 1.1 开发背景及研究意义 5 1.2 国内外研究…

数字信号处理实验---LSI系统的分析 Matlab代码

1.试用Matlab计算其幅频特性和相频特性&#xff0c;并绘图。 代码&#xff1a; n 0:10; %定义采样点n w [0:1:500]*2*pi/500; % [0,pi]轴被分成1002个点 x1 power(0.9*exp(1i*pi/3),n); %定义输入序列 x2 exp(-1i*n); %定义一个系统的冲激响应 x zeros(1,length(w))…

ESP32S3+HX8347+RGB运行LVGL例程

之前用3线SPI驱动的HX8347屏其实是一个RGB屏&#xff0c;SPI只是用来给RGB屏幕的做配置的&#xff0c;当然也可以用来驱动屏幕&#xff0c;但是3线SPI驱动能力终究有限。本文谈一下用RGB方式来驱动。 RGB接线比较多&#xff0c;为此做了个转接板&#xff1a; 一、源码 1、scre…

Swoft - Bean

一、Bean 在 Swoft 中&#xff0c;一个 Bean 就是一个类的一个对象实例。 它(Bean)是通过容器来存放和管理整个生命周期的。 最直观的感受就是省去了频繁new的过程&#xff0c;节省了资源的开销。 二、Bean的使用 1、创建Bean 在【gateway/app/Http/Controller】下新建一个名为…

Kotlin-变量定义,与类型

Kotlin-变量定义 变量定义整型浮点型字符型整型之间的转换Boolean类型Null安全安全调用Elvis运算 字符串 变量定义 Kotlin可以定义的时候不标明数据的数据类型&#xff0c;编译器会根据初始值确定类型 fun main() {var b:Intvar name "crazyit.org"//声名变量的时…

ptaR7-5打探基priority_queue的使用

题目 最近乐乐开发出了一款新的游戏《打探基》&#xff0c;这款游戏需要多人配合来玩&#xff0c;至少三个游戏玩家同时出招才能使探基的血量下降一点&#xff0c;同时&#xff0c;出招的每个人战斗力下降一点&#xff0c;当战斗力小于10的时候将不能再出招&#xff0c;不知道…

系分笔记计算机网络功能、分类和部署

文章目录 1、概述2、计算机网络的功能3、计算机网络的部署结构4、计算机网络的分类4、总结 1、概述 计算机网络是系统分析师常考查的知识点&#xff0c;虽然不是专业的网络考试&#xff0c;但是网络常识是每一个考生需要掌握的。 2、计算机网络的功能 计算机网络是计算机技术与…

计算机毕业设计 基于SpringBoot的物资综合管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

uniapp打包h5部署到服务器

在学习uniapp&#xff0c;部署前后端分离项目。将h5的dist文件打包好后一直在考虑如何通过nginx反向代理到后端接口&#xff0c;整了半天也没整成。最后才发现&#xff0c;uniapp打包的h5页面包好像不需要反向代理到后端接口&#xff0c;只需要通过nginx将dist下的h5包代理了&a…

【AI】AI和医疗大数据(2/3)

目录 四、医疗大数据理论和技术 五、非结构化处理的重要性和方法 5.1 采集技术 5.2 处理技术 5.3 存储技术 5.4 关于Mapreduce 四、医疗大数据理论和技术 医疗大数据的理论和技术主要包括以下几个方面&#xff1a; 数据整合管理技术&#xff1a;这包括多源医疗大数据的语…

【软件测试】学习笔记-从0到1:API测试怎么做

这篇文章是API测试的基础&#xff0c;先从0到1设计一个API测试用例&#xff0c;通过这个测试用例&#xff0c;体会到最基本的API测试是如何进行的&#xff0c;并介绍几款常用的API测试工具。 API测试的基本步骤 通常来讲&#xff0c;无论采用什么API测试工具&#xff0c;API测…