栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

golang调用java

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

golang调用java

最近有一个问题,是在golang作为底层,想获取apk的版本号和版本号代码(通俗一点就是versionName和versionCode),如果这时java代码,可以很容易地通过

// please add try/catch ... ;-)

PackageInfo info = context.getPackageManager().getPackageInfo(getPackageName(), 0);

String versionName = info.versionName;

int versionCode = info.versionCode;

来获取,但是,如果你的主要程序都是go语言来写,需要在go语言中获取apk的版本号怎么处理呢?

主要的解决思路有三种:

一是在你的go程序初始化的时候,通过java上层传参的形式,将这些参数传递下来

二是通过gobind来直接调用java代码

三是通过cgo来写ndk代码,调用java方法

解决思路的分析

第一种java传参给go语言入口函数

优势在于写起来非常简单,只需要go语言的接口加参数即可,然后java调用go语言代码的时候加入参数即可,缺点就是以后有新需求来的时候,还需要加参数,可能参数会越来越长…

第二种通过gobind来直接调用java代码

gobind的官方代码有这么一段:

一开始我以为我也可以在上层直接将Java代码写好,context什么的直接通过重写Appliction类,得到一个static的context,就可以在go语言中直接使用啦,心里美滋滋的…

但是,直到我将代码都写好了之后,才发现,原来gobind并不支持import自己写的类,而是已知的Android API而已…

因此,这种思路尝试到了最后不得不放弃了

第三种通过cgo来调用java代码

可以说,这个方法算是不得以而为之吧,我也是看到了go语言针对asset资源目录的处理方式才有所顿悟:

有兴趣的自己翻来看一下,具体路径$GOPATH/src/golang.org/x/mobile/asset/asset_android.go。

虽然比较难看,但写起来还是那么酷酷的。

优点是,不需要去动java上层的代码,直接在cgo里边完成需求

缺点是,相对难以理解,对于不了解jni操作的人来说维护起来相对困难,调试也不太方便

示例:获取版本号

import "C"

var getVersionOnce sync.Once

func getVersionJni() {

e := app.RunOnJVM(func(vm, env, ctx uintptr) error {

C.getVersion(C.uintptr_t(vm), C.uintptr_t(env), C.jobject(ctx))

return nil

})

if e != nil {

log.Fatalf("getVersionJni: fatal: %s", e.Error())

}

}

func GetVersion() (v string) {

getVersionOnce.Do(getVersionJni)

log.Printf("GetVersion: versionCode: %d, versionName: %s", C.versionCode, C.GoString(C.pVersionName))

return strings.TrimSpace(C.GoString(C.pVersionName))

}

这里有一个技巧,由于versionName和versionCode几乎是在运行过程不会被修改的,所以使用sync.Once来确保getVersionJni函数只会被执行了一次,后续的直接从结果里边取出来就可以了。

提示:app.RunOnJVM如果找不到方法,你可能需要升级一下gomobile。

参考链接:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/910558.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号