【问题标题】:Does Android NDK inherit Java problems?Android NDK 继承 Java 问题?
【发布时间】:2011-10-04 23:54:28
【问题描述】:

我想为 Android 创建一个游戏,我需要在 SDK 和 NDK 之间进行选择。手机硬件有限,我想避免速度变慢,但是 Java 速度慢,占用内存太多。

NDK 应用程序是否比 SDK 应用程序更快、更高效?

Java 使用垃圾收集器,所有对象都分配在堆上,我不能在另一个对象内部分配对象(没有指针),并且用作结构的简单类继承 Object 类。

我的 NDK 程序会被转换成 Java 字节码吗?编译器会忽略我的删除调用、添加垃圾收集器、添加 Object 类并将我的所有对象转移到堆中吗?

【问题讨论】:

  • 市场上的大部分Android游戏都是用Java编写的。那应该回答你的问题。
  • 谁说 Java 很慢而且占用太多内存..?
  • 我还想我会补充一点,拥有快速算法比你正在编写的语言更重要。在慢速语言中拥有一个好的算法将比在一个慢速语言中拥有一个糟糕的算法要好得多。更快的语言。
  • @ZachJullion 快速语言中的好算法优于慢速语言中的好算法。当您无法按照自己的意愿进行优化时,Java 在某些时候可能会很烦人,因为本应让您的生活“更轻松”的结构却不允许您这样做。

标签: java android performance android-ndk


【解决方案1】:

我会尝试澄清一些事情:

  • 在 Android 上,您始终使用 SDK 进行开发。您可以将 NDK 视为 SDK 的插件。 NDK 的作用是让您开发原生(例如 C/C++)代码与您的 Java 代码相伴(您在每一方面做什么取决于您)
  • NDK 应用程序更快吗?同样,这取决于你在做什么。 Java 可以在使用 JIT 的设备上快速完成很多事情。编写良好的 C/C++ 代码通常更快,是的。但是,您还必须为往返 Java/native 支付罚金(通过 JNI)
  • 如果你看的话,有一些用 NDK 编写的 Android 游戏引擎。从 NDK r5(当然还有更新的 Android 版本)开始,您无需先通过 Java/JNI 就可以从 NDK 绘制到屏幕上,这可以带来巨大的性能提升。
  • 不,您的本机代码绝对不会转换为字节码。它将被编译为原生 ARM/MIPS/x86/任何机器代码。
  • 除非您在本机代码中实现自己的 GC,否则新建、删除等行为正常。 Java VM 对您的本地分配一无所知,除非您显式调用 JNI 方法来创建新对象。

【讨论】:

  • 您确定 NDK 绘图到屏幕的性能提升吗?
  • 我指的是直接绘制vs渲染并通过JNI。
【解决方案2】:

听起来您对 NDK 与 SDK 的理解有点不清楚。

当您使用 SDK 开发应用程序时,您是在使用 Java 编写代码。当您为 NDK 开发应用程序时,您是在使用 C/C++ 编写。我想很多人会争辩说 C/C++ 对游戏来说更快(除其他外),但我相信如果你想让你的开发过程更容易,你可能想要使用 SDK;至少如果您有一个简单的 2D 游戏并且不需要使用着色器实现图形引擎,那就是这样。

您的第三段充满了许多错误的假设和错误的内涵。好像有一个垃圾收集器是不好的,堆的所有实现都是不好的,继承 Object 类的基本面向对象设计结构是不好的。是的,您可以在对象中包含对象。

不,它不会被转换为字节码。不,编译器不会忽略 delete,添加 Object 类(如何/为什么/什么?)或其他任何内容。

【讨论】:

  • 当然他的理解不清楚,这就是他提出问题的原因。这个答案没有帮助,除了最后一句话,我没有看到任何真正有用的信息。
【解决方案3】:

据我了解,NDK 仅允许您使用 C/C++ 为 Android 编写游戏(和应用程序,如果您愿意的话)。该代码被编译为 Android 机器代码,而不是以某种方式转换为 Java。然而,现代手机是否真的存在巨大的性能差异值得怀疑。

这里没有提到的 NDK 的一大优势是它允许您在较旧的 Android 版本上使用 OpenGL ES 2.0,而不是在使用 Java 时卡在 1.1 上。 OpenGL ES 2.0 已包含在 Gingerbread 中的 Java SDK 编辑:实际上它是 Froyo 而不是 Gingerbread,正如 Leif Andersen 在 cmets 中指出的那样,但至少目前,Gingerbread 还没有广泛使用 Froyo 仅在大约 60% 的 Android 手机上使用(尽管在接下来的几个月中,这一数字将继续增长)。

NDK 的另一个巨大优势是能够移植用 C/C++ 编写的 iOS 游戏(以及来自其他一些平台的游戏)。

如果您可以使用 OpenGL ES 1.1,或者想使用 2.0 但适合 Gingerbread Froyo 及更高版本,并且您没有进行任何 iOS 或其他平台端口,那么 Java几乎肯定会成为您的最佳解决方案。也就是说,除非您是一位经验丰富的 C/C++ 程序员,否则您可能更愿意使用 NDK 进行编程。

此外,使用 Java 编程的另一个优势是,如果最终有 x86 设备或其他运行 Android 的芯片,您的游戏仍然可以正常运行。使用 NDK,它必须经过专门编译才能在这些不同的芯片上运行。

【讨论】:

  • “或者想要使用 2.0 但可以很好地定位 Gingerbread 及更高版本”,实际上,它是 froyo 或更高版本,但确实需要 NDK hack,正如这个 google io 谈话所示:google.com/events/io/2011/sessions/…。另外,我相信最新版本的 NDK (r5) 也可以编译到 x86。
  • 你说的完全正确,不知怎的,我脑子里就知道这是姜饼,但实际上是 Froyo。还有关于NDK和x86,我不是说不能编译成其他架构,我只是说如果你编译上传给ARM的话,以后如果用其他架构就需要重新编译为他们而不仅仅是开箱即用。还是说它会产生一种通用的 ARM/x86 二进制文件?
  • 嗯,它不是通用的,因为它是所有三个平台都可以理解的神奇字节码,我不确定它是如何工作的。但它确实存储了所有三个平台的库版本,如果默认情况下没有发生,Application.mk 文件中的“APP_ABI := armeabi armeabi-v7a x86”行应该触发它,根据文档:developer.android.com/sdk/ndk/index.html,虽然我目前正在研究的图书馆在我这样做时会呕吐。
  • 关于我之前的评论,这似乎是一个通病:groups.google.com/forum/#!topic/android-ndk/Y1ozOWg1CywRats.
  • 所以看起来多架构支持有点像 NDK 的 PITA,这几乎就是我所得到的。使用纯 Java SDK,您不必担心架构。 /// 当我说通用二进制时,我的意思是像 OS X 一样,将多个架构的二进制文件打包到一个文件中,而不是神奇的字节码,尽管那会非常棒:P
猜你喜欢
  • 2011-03-15
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多