使用 Multi-OS Engine 在 Apple Mac OS X 上构建您的第一个 Android 和 iOS 应用





0/5 (0投票)
本教程将指导你使用安装在 Mac OSX 上的 Multi-OS Engine 构建你的第一个跨平台应用程序,我们称之为本地构建。
Intel® Developer Zone 提供用于跨平台应用开发、平台和技术信息、代码示例以及同行专业知识的工具和操作指南,以帮助开发人员创新并取得成功。加入我们的社区,了解 Android、物联网、Intel® RealSense™ 技术和 Windows,下载工具、访问开发套件、与志同道合的开发人员分享想法,并参与黑客松、竞赛、路演和本地活动。
本教程将指导你使用安装在 Mac OSX* 上的 Multi-OS Engine 构建你的第一个跨平台应用程序,我们称之为本地构建。你也可以在 Windows* 上的 Android Studio 中开发你的 Android* 和 iOS* 应用程序,但为了模拟你的 iOS 应用程序,你需要远程部署你的应用到一个运行 Xcode* 的 Mac 系统(即远程构建)。对于这种情况,请查看我们关于 Multi-OS Engine(远程构建)的入门指南。
在本教程中,我将向你展示如何创建一款简单的“Hello World”应用程序,支持 Android 和 iOS,并在这两个应用程序之间共享代码。在实际场景中,你的大部分应用程序逻辑都会被共享。
必备组件
要开始,你需要满足以下最低软件要求
- Android Studio* 1.0 或更高版本
- Xcode* 6 或更高版本
- Java* Development Kit 1.7 或更高版本
- Android SDK
整体工作流程
创建 Android 和 iOS 应用程序的工作流程相对简单。
- 为了在 Android Studio 中创建 iOS 应用程序,我们首先需要从一个 Android 项目开始。
- 然后我们创建一个 Multi-OS Engine 模块(这将是 iOS 应用程序)
- 为了应用程序代码共享,我们创建一个名为 "common" 的模块(共享 Java 库)
- 然后我们将 "common" 模块添加为 Android 和 iOS 应用程序的依赖项
- 最后,我们配置 Gradle* 脚本,构建并启动我们的应用程序。
创建我们的第一个 Android 和 iOS 应用程序(具有共享逻辑)
在“项目”窗格中,右键单击任意位置,选择“新建”>“Intel Multi-OS 模块”
- 在 Android Studio 中创建 Android 项目
- 输入你的应用程序名称、公司域名,并选择要保存项目的目录。一个好的做法是将你的项目存储在用户名的“Project”文件夹下。你可能希望遵循此处描述的确切步骤,以确保你不会遇到任何问题。请注意自动生成的程序包名称 (
com.mycompany.myfirstapp
),它是小写字母。单击“下一步”。 - 配置你的目标设备和 API 级别设置。如果你只想开始,只需单击“下一步”继续使用默认设置。
- 在“添加活动到移动设备”窗口中选择“空白活动”,然后单击“下一步”。
-
在“自定义活动”窗口中,你可能希望保持设置不变。单击“完成”接受默认配置。
-
此时,Android Studio 已创建一个 Android 项目。在“项目”窗格中,你会注意到 "app" 模块。此模块是你的 Android 应用程序。我们现在将继续添加 Multi-OS Engine 模块,这将最终成为你的 iOS 应用程序。
- 单击“Hello World 应用程序”,然后单击“下一步”
-
在此窗口中,你将创建一个 Xcode 项目。稍后你可能希望在 Xcode 中打开 Android Studio 创建的 iOS 项目,特别是如果你想使用 Xcode 的 Storyboard 来设计你的原生用户界面。输入Xcode 项目名称(通常是你的应用程序名称)、产品名称(应用程序名称)、组织和公司 ID 详细信息。
在此示例中,我们将输入以下详细信息以匹配 Android S
Xcode 项目名称:myfirstapp产品名称:myfirstapp组织名称:mycompany公司标识符:com.mycompany
- 单击“下一步”配置新模块。该模块将是 iOS 模块。因此,让我们将其命名为“iOS”。单击“完成”。
我们现在已在 Android Studio 中创建了一个 iOS 应用程序。如果 Android Studio 提示你同步 Gradle 脚本,请执行此操作。在接下来的步骤中,我们将创建一个“common”模块,顾名思义,它将包含我们 Android 和 iOS 应用程序的通用 Java 代码。
现在,让我们继续创建一个“common”模块,它将包含我们共享的应用程序逻辑(Java)。在我们简单的示例中,我们的共享逻辑将只是一个 Java 对象,它有一个名为
sayHello()
的方法,该方法返回一个 Java String。 - 再次在“项目”窗格中,右键单击并添加一个新的模块:
- 在“新建模块”窗口中,选择“Java 库”,然后单击“下一步”。
- 我们记得这个库将包含我们所有的共享(common)应用程序逻辑。因此,让我们将其命名为“common”,并将我们的第一个 Java 类命名为“AppLogic”。请根据为其他模块生成的模式编辑 Java 包名。通常,它将是这样的:
company_domain_in_reverse.appname.common
,例如com.mycompany.myfirstapp.common
-
单击“完成”,让 Android Studio 刷新“项目”窗格和 Gradle 脚本。
我们现在将向我们的
AppLogic
类添加一些代码。 -
导航到common > java > com.mycompany.myfirstapp.common 并打开
AppLogic
类。用以下内容替换其内容(粗体显示的代码是新添加/编辑的行)package com.mycompany.myfirstapp.common; public class AppLogic { private String myString; public AppLogic(){ this.myString = "Hello World from common"; } public String sayHello(){ return this.myString; } }
最后,让我们将 common 模块添加为 Android 和 iOS 应用程序的依赖项。注意:在“项目”窗格中,它们分别称为“app”和“iOS”。
- 选择任何模块的根(目前你有三个,即 app、iOS 和 common)。右键单击并选择打开模块设置。
-
对于**所有** app 和 iOS 模块,在依赖项选项卡中添加 common 模块。要做到这一点,请单击底部的 + 号,然后单击模块依赖项,然后在列表中选择 common。
将 common 模块添加为 iOS 模块的依赖项后,iOS 的模块设置应如下所示
对 app 模块也执行上述操作:
-
common 模块中的 Java 代码将由 Java 编译器编译。该模块有自己的 Gradle* 脚本用于构建过程。我们需要更新脚本以告知 Gradle 将使用哪个版本的 Java 来编译我们的模块。打开 common 模块的 Gradle 脚本(Gradle Scripts > build.gradle (Module: common))并在末尾添加以下内容
compileJava { targetCompatibility = 1.7 sourceCompatibility = 1.7 }
现在,让我们编写一个带有按钮和文本字段的小型 Android 应用程序。当你单击文本字段时,你将调用共享的
AppLogic
对象的sayHello()
方法。 -
对于 Android 应用,打开 activity_main 布局(app>res>layout>activity_main.xml)。如果你看到 XML 代码,只需单击底部的设计选项卡切换到图形界面。应该已经有一个Hello World 文本字段。让我们通过将一个按钮从调色板拖放到手机上来添加一个按钮。双击该按钮并将其重命名为“Click Me!”。请注意,按钮的 ID 称为“button”。Android 通过 ID 在屏幕上定位元素。现有的Hello World 文本的 ID 是 textView。你可以在“组件树”窗格或 XML 文件中看到这一点(要查看 XML 代码,请单击底部的文本选项卡)。
-
接下来在我们的 MainActivity(app > package com.mycompany.myfirstapp > MainActivity)中,我们导入我们的 common 模块并为我们新创建的按钮添加一些逻辑(参见代码片段 1)。粗体行是添加的代码。对于 Android SDK 中提供的 Button 和 View 等类,你始终可以按 Option+Enter 来自动导入相关的程序包。
-
可选:你可以在真实设备或模拟器上测试新的 Android 应用。你可以通过编辑 Android 应用的配置来执行此操作。在配置菜单中,你可以选择目标设备。有关在真实设备或虚拟设备上执行应用的更多信息,请参考官方 Android 文档。
现在,让我们创建 iOS 应用。
-
在“项目”页面中,打开 AppViewController java 文件。(iOS > java > com.mycompany.myfirstapp > ui > AppViewController)。编辑代码以导入 common 模块并向按钮添加必要的逻辑。注意:在添加 Hello World Multi-OS Engine 模块时,系统会自动创建一个按钮。有关完整的代码,请参见下面的代码片段 2。粗体行是已添加/编辑的行。
- 我们的 iOS 应用的代码已准备就绪。从那里,让我们在 iOS Simulator 中执行 iOS 应用。为此,从下拉菜单中选择 iOS,如下面的屏幕截图所示
-
Voilà!你现在拥有一个经典的 Hello World 应用程序,它在 Android 和 iOS 上运行,并且代码是共享的。
这很棒!接下来我该怎么办?你可能想查看我们在示例文件夹中的更高级的示例:
/Applications/Intel/INDE/multi_os_engine/samples
随时随地玩耍。如果你有任何困难,请随时在我们专用论坛上提问。另外,请留意我们的博客,了解有关 Multi-OS Engine 的更新和功能。
代码片段
代码片段 1 – Android (MainActivity.java)
package com.mycompany.myfirstapp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem;import android.view.View; import android.widget.Button; import android.widget.TextView; /* Import our common module */ import com.mycompany.myfirstapp.common.*; public class MainActivity extends AppCompatActivity { AppLogic al = new AppLogic(); Button button; TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); tv = (TextView) findViewById(R.id.textView); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { tv.setText(al.sayHello()); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
代码片段 2 – iOS – AppViewController.java
package com.mycompany.myfirstapp.ui; import com.intel.inde.moe.natj.general.NatJ; import com.intel.inde.moe.natj.general.Pointer; import com.intel.inde.moe.natj.general.ann.Generated; import com.intel.inde.moe.natj.general.ann.Owned; import com.intel.inde.moe.natj.general.ann.RegisterOnStartup; import com.intel.inde.moe.natj.objc.ObjCRuntime; import com.intel.inde.moe.natj.objc.ann.ObjCClassName; import com.intel.inde.moe.natj.objc.ann.Property; import com.intel.inde.moe.natj.objc.ann.Selector;import com.mycompany.myfirstapp.common.AppLogic; import ios.NSObject; import ios.uikit.UIButton; import ios.uikit.UILabel; import ios.uikit.UIViewController; @com.intel.inde.moe.natj.general.ann.Runtime(ObjCRuntime.class) @ObjCClassName("AppViewController") @RegisterOnStartup public class AppViewController extends UIViewController { AppLogic al = new AppLogic(); static { NatJ.register(); } @Generated("NatJ") @Owned @Selector("alloc") public static native AppViewController alloc(); @Generated("NatJ") @Selector("init") public native AppViewController init(); @Generated protected AppViewController(Pointer peer) { super(peer); } public UILabel statusText = null; public UIButton helloButton = null; @Override @Selector("viewDidLoad") public void viewDidLoad() { statusText = getLabel(); helloButton = getHelloButton(); } @Selector("statusText") @Property public native UILabel getLabel(); @Selector("helloButton") @Property public native UIButton getHelloButton(); @Selector("BtnPressedCancel_helloButton:") public void BtnPressedCancel_button(NSObject sender){ statusText.setText(al.sayHello()); } }