找回密码
 立即注册
查看: 1398|回复: 20

[笔记] 请问 Android APP 用 Java 开发的,游戏引擎用 unity 3D,语言是C#怎么回事?

[复制链接]
发表于 2021-4-22 09:50 | 显示全部楼层 |阅读模式
列如崩坏3是安卓上的,但引擎是unity 3D,所以要用到C#,但是安卓上的软件不是java开发的吗?
发表于 2021-4-22 09:56 | 显示全部楼层
首先,Android 设备可以运行 C/C++ 写的原生代码。构建 Android 项目时,这些代码会编译到原生库,然后打包进 APK 中。然后,Java 或 Kotlin 代码即可通过 Java 原生接口 (JNI) 调用原生库中的函数。
使用 C# 编写的 Unity 应用可以编译成 .Net 字节码。使用 Unity 的 Android 应用包含一个基于 Mono 的字节码解释器。运行 Android APP 时,解释器能够执行 .Net 字节码。这就是为什么 Unity 程序能够在 Android 上运行。
王者荣耀也是使用的 Unity 3D 开发的,下面以它为例,让我们看一下王者荣耀2个G的安装包里都有什么。这样更容易理解以上我们提到的的一些结论。
里面只有两个 Java 编译生成的 dex 文件,大小仅有6.2MB,而 assets 文件夹则足足占了 1830MB。


打开 assets 文件夹,可以看到 1740MB 的数据库还有一些 mono 和 unity 配置文件。验证了前面我们的说法。


lib 目录下则是有着游戏核心和 Unity 相关的由 C/C++ 编译生成的 so 库。这些库可以被 Java 通过 JNI 调用。
本人只是 Android 原生应用开发者,非专业游戏开发人员,如果理解有误,欢迎交流。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-4-22 10:00 | 显示全部楼层
你理解的没错,安卓必须要用Java开发,而崩坏3或其他软件,他们不是用Java写的(比如用C#),但是也运行在了安卓上。


要理解这是咋做到的,首先呢,先讲一个基本概念:安卓是基于Linux开发的
众所周知的是,Linux作为一个开源开放的操作系统,可以运行世界上所有的语言(虽然不严谨,但是姑且这么理解吧)。哪怕是属于微软的C#,也在Linux上有运行环境mono。Linux这么强的原因,是因为Linux允许开发者直接运行汇编代码(机器码),而世界上所有的语言,其实都是可以编译成汇编(机器码)的。
PS:mono其实是一个跨平台的C#运行环境,也有Windows版 macOS版。而且mono和微软的关系还是挺有意思的,现在已经被微软收购了,马上就会和微软自己的开源C#运行环境.NET Core合并

而安卓是基于Linux的,按道理也可以运行世界上所有的语言。。。但为啥我们会说,安卓app都是用Java写的呢?那是因为,谷歌在安卓系统里加了不少限制:
安卓不允许开发者直接运行汇编代码(机器码),相反,如果用户启动一个app,安卓就会直接打开一个java运行环境,然后这个java运行环境直接去运行apk里的java字节码,不给开发者直接运行汇编代码(机器码)的机会;同时,如果开发者想在安卓系统的界面上显示出app样式,谷歌也只给了java代码的接口——Linux或者其他操作系统,给的都是二进制汇编接口。


那么,安卓是怎么做到运行其他语言的呢?
其实,根据Java的语言规范,Java允许开发者在Java运行环境中调用本地的汇编代码(机器码),这个功能被称为JNI(Java Native Interface)。JNI还允许汇编代码直接去和Java代码沟通。。。


所以说,安卓运行其他语言,比如崩坏3的C#,是这么做到的:
    用户按下崩坏三的图标后,安卓系统打开一份java运行环境这份java运行环境打开崩坏3中的java代码,开始运行崩坏3中的java代码,调用JNI,去打开一个C#的运行环境(mono)mono开始运行真正的崩坏3游戏代码,输出游戏图像游戏图像重新通过JNI,传回给崩坏3的java代码java代码调用系统接口,显示出游戏图像。。。。


这是安卓上运行其他语言的通用做法了,哪怕是谷歌自己的flutter app(编程语言是Dart,不是java),都是通过这个办法运行在安卓上的。。。。


(所以谷歌你造什么孽,给安卓加java的限制呢。。。。。)


最后,回答你的问题:开发android软件到底是用java还是C#?
是Java,无论如何都绕不过Java;但是可以用C#或者其他语言开发出app的主体,然后用Java去调用,从而实现用别的语言开发安卓。
发表于 2021-4-22 10:01 | 显示全部楼层
没冲突啊,unity那是它的脚本语言是用c#而已,它也可以用lua用js,最后它会打包成Android可读的二进制代码安装包。而Java也只是开发语言而已,最后它依然会被翻译成对应的Android二进制代码运行,所以原理并没是不同的
发表于 2021-4-22 10:11 | 显示全部楼层
目前看到其它回答似乎都还没有解释清楚  C#代码在安卓上如何运行。
和JVM能够解释执行Java字节码一样,Mono可以解释执行.NET字节码,C#代码编译为.NET字节码之后,可以运行在Android版本的Mono环境之上。
Mono只是一种方法,还有另一种方法是IL2CPP。在C#代码编译为.NET IL代码之后,IL2CPP再把IL代码转换为C++代码,之后再在Android构建过程中编译C++。
如题主所说Android SDK是基于Java语言的开发工具,但是Android开发不等于Java开发,Android NDK使用的就是C和C++。
其实拿Windows类比一下这个问题就很好理解了。Windows桌面应用程序目前主流的开发语言是C#,那么Java程序如何在Windows上运行?在运行时环境的支持上,操作系统提供了基本相同的机制。
发表于 2021-4-22 10:16 | 显示全部楼层
首先,现在Android官方推荐的开发语言不是Java,而是Kotlin (当然Java依然能用)
然后,即使不谈Unity,C#本身就是可以开发跨平台应用的。(详细参考mono相关的资料)
其实除此之外,很多语言,包括C++都能开发Android应用。
然后具体说入门应该学啥的问题,
如果想成为一个开发APP的程序员,通常建议学Java(目前Java用的地方最多),然后Java会了之后稍微花点时间学kotlin
如果再有兴趣,学学Dart
发表于 2021-4-22 10:24 | 显示全部楼层
首先你要搞清楚几件事,1.安卓上游戏和普通软件app是两回事 不是一个东西!安卓上的普通软件类型的app,绝大部分是java(或kotlin,也是运行在java环境下)开发的,除了少部分跨平台的方案,这是因为谷歌官方提供了一套基于java语言的UI框架,做软件都在这个框架下做,各种各样界面元素都是这个框架提供的。但游戏不是,难道你觉得游戏和普通软件是长一样的?我相信任何使用过普通功能型软件和游戏的人,都能看出来这两个完全长得不一样。
2.难道安卓上只能运行java吗?安卓是一个操作系统,你pc上各种语言开发的软件都能运行,安卓怎么就不行?只要你抛开谷歌官方提供的那一套UI框架不用,你想怎么样搞都行,难道没听说过C++ 的QT库也能开发安卓吗,最新流行的Flutter框架使用dart语言。而游戏明显不可能使用一般软件的UI框架,游戏是实时渲染的,对性能要求更高,游戏一般使用游戏引擎开发,移动游戏一般调用底层的opengl es,使用GPU硬件渲染,简单说就是自成体系,不依赖UI框架。这也就是为什么很多游戏引擎都能跨平台的原因。
3 .最后一点C#为什么能在安卓运行,我觉得这都不叫问题。如你所说,那么为什么java能在安卓运行?cpu又不认识java字节码,cpu只认识机器码,因此java能运行,就需要runtime,目前安卓上也是运用jit技术,将java字节码翻译成机器码,让cpu执行,一模一样的道理,C#再来一次,有什么稀奇?我更好奇的是,你为啥不问java为什么能在安卓运行?你可能还有一个疑问,为什么不用C#开发安卓app,这道理就更简单了,因为谷歌提供的UI框架是java语言写的,java调java。谷歌为啥当年不选择C#,答案也很简单,因为C#一直不受待见,早期就是个边缘化小众技术,就算现在,也主要就是U3D上用用,其他领域根本没太大存在感,更何况现在是移动端天下,微软在移动上一败涂地
发表于 2021-4-22 10:31 | 显示全部楼层
这个东西,就像你开个面馆,面都是手工做的,和面压面切面,弄成面条,然后煮面。


然后觉得自己手动做面效率太低了,就联系了一个专门做面条的,但是不是他随便做都可以啊,就给他定了个标准,面多长多粗多细,不管他是自己手工做,机器做,甚至是买其他人的再卖给你,只要符合要求,那就和自己做的差别不大,就能做这个面。


基本上就这个意思 android自己提供的手工面套装工具就是java kotlin cpp,你觉得不好用不顺手,就找了一个第三方供应商如unity,unity用的工具套装就是c#。
发表于 2021-4-22 10:34 | 显示全部楼层
首先需要知道的是android基于linux内核
题主所例举的程序都在dalvik虚拟机环境中运行
dalvik虚拟机执行的实际上是.dex文件,在linux中c也是被支持的,可以执行.so文件
而java编译结果.class或者.jar都是不能直接执行的
而是由android平台工具编译为.dex执行
从本质上来说,dalvik只是能够支持java语言,并不限制非要是java


而unity跨平台的原理依赖的是unity引擎
这个引擎在各个系统都有提供,对上层屏蔽系统差异,并不只是c# ,js也可以写吧
从我的理解来说就是Ue对c#的支持是提供了clr的支持,通过jit转为native方法运行
发表于 2021-4-22 10:34 | 显示全部楼层
傻孩子,C#才是真正跨越一切平台的编程语言,而Java早已退居后台开发了。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-16 08:19 , Processed in 0.103909 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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