跨平台 iPhone / Android 代码共享

39

简单来说:在iPhone和Android构建之间分享/重用代码的最有效方法是什么?

我认为最常见的两种情况可能是:

  1. 全新的空白项目,事先知道需要在每个设备上运行大量可重用逻辑。
  2. 现有的iPhone代码库,将C、C++和Objective-C移植到Android NDK或其他平台。

当然,在一个完美的世界里,所有应用程序都可以插入魔法云中,并且所有可重用逻辑都会出现在Google App Engine或某些Web服务中,但这不是本问题的精神所在。通过间接经历了一次从iPhone到Android的无代码重用移植,并看到那个人所经历的痛苦后,我想知道其他人是如何避免这种情况的。


请参见https://dev59.com/eG865IYBdhLWcg3wFqdV。 - David d C e Freitas
11个回答

21

根据我的经验,您可以使用Android NDK编译C和C ++代码。因此,如果在iPhone上使用Obj-C ++(.mm)绑定将C ++ / C引擎绑定到iPhone上,并且在Android上使用Java绑定将相同的引擎绑定到Android上,这完全是可行的。

因此,C ++ / C引擎(在Android和iPhone上几乎相同的代码库)+轻量级绑定层=可移植代码。


Apportable SDK基于Android NDK构建,可以编译C、C++和Objective C,并添加库以匹配大部分iOS API。 - Paul Beusterien
虽然Apportable已经倒闭,但是你可以使用GNUstep Android工具链作为替代方案,在Android上编译Objective C代码(请参见下面我单独的回答)。 - Frederik

9

就像我之前告诉一个问了一个类似问题的人一样,使用MVC并在C++中实现MC,V则在obj-c或Java中实现。


这并不是一个很好的想法,因为如果没有Objective-C和Cocoa绑定用于M+C,你最终会得到一些非常不优雅和原始的东西。 - user52898
1
如果您正在考虑框架提供的MVC绑定或自动生成的代码,这些都不需要使用,可以自己编写接口层。此外,您所考虑的低雅和原始的标准是什么? - Hassan Syed
也对此很好奇。 - Tristan

5

尽可能使用纯C(或必要时使用C++)编写,并在Android和iPhone中包含相同的文件。也适用于Windows/Mac。"跨平台"库往往会使你望而却步。


5
尽可能在传统的C语言中编写你的逻辑是一个不会出错的选择。 - zumalifeguard

3
你可以尝试使用Marmalade SDK... 只需编译一次即可生成本地ARM二进制文件,并在Android和iPhone上部署,使用标准的C/C++语言,可以在Windows或Mac上进行开发,还包括许多(可选的)中间件技术。

2
"

XMLVM 看起来值得一试。

"

2

我一直在使用Lua和自己的框架为iPhone创建应用程序和游戏。这样我就可以最终使用Android NDK为Android实现相同的框架,但是实际的应用程序代码希望在两个平台上完全相同。

我认为没有简单的方法可以做到这一点,因为API显然不同,本机编程语言也不同,但是建立自己的框架在任何被两个平台支持的语言中都是我的建议。也许已经有一个框架可以替你完成繁重的工作?如果没有好的框架来完成这项工作,那么这显然是实现一个框架的机会。


+1 提出LUA的话题 - 非常好的观点,我认为人们正在忘记它。 - slf

1
你可以使用Scapix语言桥自动将C++与Java和ObjC/Swift(以及其他语言)进行桥接。在运行时直接从C++头文件生成桥接代码。以下是示例
在C ++中定义类:
#include <scapix/bridge/object.h>

class contact : public scapix::bridge::object<contact>
{
public:
    std::string name();
    void send_message(const std::string& msg, std::shared_ptr<contact> from);
    void add_tags(const std::vector<std::string>& tags);
    void add_friends(std::vector<std::shared_ptr<contact>> friends);
};

并从Swift中调用:

class ViewController: UIViewController {
    func send(friend: Contact) {
        let c = Contact()

        contact.sendMessage("Hello", friend)
        contact.addTags(["a","b","c"])
        contact.addFriends([friend])
    }
}

来自Java:

class View {
    private contact = new Contact;

    public void send(Contact friend) {
        contact.sendMessage("Hello", friend);
        contact.addTags({"a","b","c"});
        contact.addFriends({friend});
    }
}

1

Moai对于小型项目是免费的,同时也被大型工作室所使用。我自己运行homebrew,但如果没有的话,我可能会使用Moai,因为它看起来非常有前途。他们声称它可以移植到Mac、PC、iOS、Android甚至Kindle Fire。

我猜你会想要用Lua编写大部分代码,但你可以访问所有的代码,所以在需要时可以使用C++。


@slf:你自己用过吗?如果用过,你觉得怎么样? - Jonas Byström
我还没有听说过这个,这是我第一次听到,不过看起来它有潜力。 - slf

1

我使用BatteryTech来进行平台抽象和项目结构的搭建,我的项目结构如下:

在我的PC上:

gamename - 只包含通用代码

gamename-android - 主要包含BatteryTech的Android特定代码和Android配置,构建器指向gamename项目以获取通用代码

gamename-win32 - 仅用于Windows构建,使用gamename项目中的代码

在我的Mac上:

gamename - 只包含通用代码

gamename-ios - iPhone/iPad构建,导入通用代码

gamename-osx - OSX本地构建,导入通用代码。

我使用SVN在我的PC和Mac之间共享。我的唯一真正的问题是当我在Windows中向通用代码库添加类,然后在Mac上更新以从SVN拉取它们时。XCode没有自动将它们添加到项目中的方法,所以每次都必须手动添加,这很麻烦,但并不是世界末日。

所有这些东西都随着BatteryTech一起提供,一旦你掌握了它,就很容易理解。


Xcode无法自动添加新文件,这一点我赞同。我猜是因为它的目录/文件夹/组项目结构比较松散,所以不知道要将它们添加到哪个项目中。 - Tomas Andrle

0
如果你有一份现有的 Objective C iOS 代码库,你可以使用 GNUstep Android 工具链来在 Android 应用中使用基于 Foundation 和 CoreFoundation 的现有模型代码,并通过本地 NDK 调用与 Objective C 模型交互,然后在其上编写新的 UI 层(例如在 Android Studio 中)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接