Intel Multi-OS Engineを使用してJava iOSアプリケーションを開発した経験

8月、サンフランシスコのIntel Developer Forumで、 Intel Multi-OS Engineプラットフォームを使用して開発された、患者モニタリング用のiPad用ネイティブモバイルアプリ発表しました。 アプリケーションは、患者の状態の最も重要なパラメーターに関するデータを提供し、WiFiネットワークを介してベッドサイドモニターに接続します(アプリケーション自体とその機能の詳細については、 当社のWebサイトをご覧ください )。

この記事では、Intel Multi-OS Engineプラットフォームを使用した経験を共有します。これにより、JavaでネイティブiOSアプリケーションを開発できます。



AndroidとiOSの両方のアプリケーションを開発する必要がある場合、Javaを使用してiOS用のアプリケーションを開発する機能により、時間と開発リソースを節約できます。



Intel Multi-OS Engineを使用する主な利点



UIElements



経験に基づいて、Multi OS-Engineプラットフォームの主な肯定的な機能は、Xcodeとほぼ同じネイティブiOS UI要素を操作できることです。 アプリケーションの開発に必要なすべての要素はすでにプラットフォーム上にあったため、追加する必要はありませんでした。 各要素について詳しく説明します。すべての特性とメソッドが存在するため、iOSの経験がある開発者にとってプラットフォームの作業が簡単になります。

アプリケーションの適切な構成

このプラットフォームにより、AndroidおよびiOS用のアプリケーションをすぐに開発できるようになるため、アプリケーションのアーキテクチャの開発には細心の注意を払い、共通の機能とUI固有の機能を正しく区別する必要があります。 これにより、非常に正確で軽量なアプリケーションを構築し、開発者を編成できます。



Java機能



このプラットフォームの利点は、Javaのほとんどの機能を実装できることです。 たとえば、ストリームとファイルの操作を検討してください。



Thread thread = new Thread() { public void run() { } }; thread.start(); private void openFileToRead() { String fileId = "hb"; NSBundle mainBundle = NSBundle.mainBundle(); String pathToFile = mainBundle.pathForResourceOfType(fileId, "dat"); File file = new File(pathToFile); FileInputStream fis = null; try { fis = new FileInputStream(file); DataInputStream dis = new DataInputStream(fis); //-   input stream } catch (IOException e) { e.printStackTrace(); } }
      
      





その過程で、ネットワークの操作に関する追加調査を実施しましたが、RetrofitフレームワークはokHttpと連携してうまく機能することがわかりました。



JavaでiOS固有の部分を便利かつ迅速に記述



さらに、ObjCアプローチを使用してバックグラウンドで実行できます。 私たちの場合、アプリケーションの起動時に、ファイルの読み取りプロセスを開始しました。



 @Override @Selector("application:didFinishLaunchingWithOptions:") public boolean applicationDidFinishLaunchingWithOptions(UIApplication application, NSDictionary launchOptions) { performSelectorInBackgroundWithObject(new SEL("initQueueDispatcher"), null); return true; } @Selector("initQueueDispatcher") @Generated public void initQueueDispatcher() { QueueDispatcher.sharedQueueDispatcher().initQueue(); }
      
      





メインスレッドで個々の関数を実行することも問題ではありません。



 public void heartRate(PatientRealData data) { performSelectorOnMainThreadWithObjectWaitUntilDone(new SEL("updatePatientData:"), } @Selector("updatePatientData:") @Generated public void updatePatientData(PatientRealData data) { mHrLabel.setText(String.valueOf(data.getHeartRate())); }
      
      





リソースへのアクセスはiOS APIに似ています:「alarm_on.png」画像をリソースから取得してボタンに割り当てるには、次のようにします。



 UIImage image = UIImage.imageNamed("alarm_on"); mAlarmButton.setImageForState(image, UIControlState.Normal);
      
      





JavaでiOS APIを操作するための構文は、ObjCのオリジナルと実質的に同じであることが非常に便利です。 たとえば、UITableViewControllerに基づくメニューは次の方法で追加されました。



 @com.intel.inde.moe.natj.general.ann.Runtime(ObjCRuntime.class) @ObjCClassName("PatientsTableVC") @RegisterOnStartup public class PatientsTableVC extends UITableViewController { static { NatJ.register(); } @Generated("NatJ") @Owned @Selector("alloc") public static native PatientsTableVC alloc(); @Generated("NatJ") @Owned @Selector("init") public native PatientsTableVC init(); @Generated("NatJ") protected PatientsTableVC(Pointer peer) { super(peer); } private ArrayList<PatientInfo> mPatients = new ArrayList<PatientInfo>(); @Selector("prefersStatusBarHidden") @Override public boolean prefersStatusBarHidden() { return true; } @Selector("viewDidLoad") @Override public void viewDidLoad() { setTitle("Select patient:"); } @Selector("numberOfSectionsInTableView:") @Override @NInt public long numberOfSectionsInTableView(UITableView tableView) { return 1; } @Selector("tableView:numberOfRowsInSection:") @Override @NInt public long tableViewNumberOfRowsInSection(UITableView tableView, long section) { return mPatients.size(); } @Selector("tableView:cellForRowAtIndexPath:") @Override public UITableViewCell tableViewCellForRowAtIndexPath(UITableView tableView, NSIndexPath indexPath) { String reusableId = "patientCell"; UITableViewCell cell = (UITableViewCell) tableView.dequeueReusableCellWithIdentifierForIndexPath(reusableId, indexPath); PatientInfo patient = mPatients.get((int) indexPath.row()); cell.textLabel().setText(patient.description()); return cell; } @Selector("prepareForSegue:sender:") @Generated public void prepareForSegueSender(UIStoryboardSegue segue, NSObject sender) { NSIndexPath indexPath = tableView().indexPathForSelectedRow(); PatientInfo patient = mPatients.get((int) indexPath.row()); MainMonitorVC controller = (MainMonitorVC) segue.destinationViewController(); controller.setPatient(patient); } }
      
      





Android Studio用のマルチOSエンジンプラグイン



Intelプラットフォームの深刻な利点は、Multi-OS EngineプラグインのAndroid Studioへの統合の「深さ」です。 Android Studioでほぼすべての開発を実行できます。 この場合、2つのプラットフォームで同時に動作するようにプロジェクトを簡単に構成できます。 これを行うには、AndroidバージョンとiOSバージョンを起動するように構成を構成し、必要なバージョンを選択するだけでそれらを切り替えます。







チャートの接続



「実行中の」グラフの表示を実装するために、Cで記述されたOpenGL操作方法を使用しました。それらを使用するために、ObjCでUIコードを既に追加したUIWaveFormVCコントローラーを作成しました。 入力データに従って、このコントローラーはOpenGLビューに指定された速度と色で対応するポイントを描画します。



 UIWaveFormVC.h @interface UIWaveFormVC : GLKViewController @property (nonatomic, strong) DPSampleQueue * inputQueue; - (void)setDataQueue:(DPSampleQueue *) dataQueue; - (void)setWaveColor:(UIColor *)waveColor; - (void)setSampleFreq:(float)sampleFreq; UIWaveFormVC.m #import "UIWaveFormVC.h" @interface UIWaveFormVC () @property (strong, nonatomic) EAGLContext * context; @end - (void)setDataQueue:(DPSampleQueue *) dataQueue { self.inputQueue = dataQueue; } - (void)viewDidLoad { [super viewDidLoad]; self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; if (!self.context) NSLog(@"Failed to create ES context"); } - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { //     }
      
      





さらに、Multi OS-Engine内でこのクラスを使用するには、「ラッパー」を生成する必要があります。つまり、ObjCにJavaバインディングを実装する必要があります。



 UIWaveFormVC.java @com.intel.inde.moe.natj.general.ann.Runtime(ObjCRuntime.class) @ObjCClassName("UIWaveFormVC") @RegisterOnStartup public class UIWaveFormVC extends GLKViewController { @Generated("NatJ") protected UIWaveFormVC(Pointer peer) { super(peer); } @Selector("setDataQueue:") @Generated public native void setDataQueue(DPSampleQueue dataQueue); @Selector("setWaveColor:") @Generated public native void setWaveColor(UIColor waveColor); @Selector("setSampleFreq:") @Generated public native void setSampleFreq(float sampleFreq); static { NatJ.register(); } }
      
      





次に、 MainUI.storyboardの画面ロジックにUIWaveFormVCを追加するだけです



その後、すべての作業はJavaから直接行われます。 データをUIWaveFormVCに転送するには、 prepareForSequeSender()メソッドを宣言します。これにより、表示する前にコントローラークラスのインスタンスを取得し、データを渡すことができます。



 @com.intel.inde.moe.natj.general.ann.Runtime(ObjCRuntime.class) @ObjCClassName("MainMonitorVC") @RegisterOnStartup public class MainMonitorVC extends UIViewController { static { NatJ.register(); } @Selector("alloc") public static native MainMonitorVC alloc(); @Selector("init") public native MainMonitorVC init(); @Generated("NatJ") protected MainMonitorVC(Pointer peer) { super(peer); } private QueueDispatcher mQueueDispatcher = null; @Selector("prepareForSegue:sender:") @Generated public void prepareForSegueSender(UIStoryboardSegue segue, NSObject sender) { if (segue.identifier() == null) return; UIWaveFormVC controller = (UIWaveFormVC) (segue.destinationViewController()); controller.setDataQueue(sharedQueueDispatcher().queueWithID(segue.identifier())); controller.setSampleFreq(SAMPLE_FREQ); controller.setWaveColor(WAVE_GREEN); } private QueueDispatcher sharedQueueDispatcher() { if (mQueueDispatcher == null) { mQueueDispatcher = QueueDispatcher.sharedQueueDispatcher(); mQueueDispatcher.startDataLoading(); } return mQueueDispatcher; } }
      
      





Intel Multi-OS Engineを改善するための推奨事項



•データベースのODBCドライバーがサポートされていないため、AndroidおよびiOSバージョン用に1つの統合データベースをすぐに作成するのは問題です。

•iOSでhttpsをサポートするには多少の努力が必要です。Androidビルドから証明書を手動で追加する必要があります。

•サードパーティライブラリを使用する場合、プロガード設定を変更する必要がある場合がありますが、Gradleを使用して標準的な方法で変更することはできません。 その結果、必要なフラグを手動で追加する必要があります。

/ Applications / Intel / INDE / multi_os_engine / toolsにあるproguard.cfgファイルでこれを行うことができます 。 フラグはファイルの最後に追加するだけです。 この場合、次のフラグを追加してRetrofitを使用します。



 -keepattributes *Annotation* -keep class retrofit.** { *; } -keepclasseswithmembers class * { @retrofit.http.* <methods>; } -keepattributes Signature
      
      





•Android Studioでストーリーボードを直接編集する方法はなく、Xcodeでインターフェイスを設定する必要がありました。



モバイルソリューションの開発プロジェクトでは、Intel Multi-OS Engineプラットフォームを引き続き使用します。この経験は、独自の専門知識を獲得し、複雑なR&Dタスクに対処する能力を示す新たな機会だと考えているためです。



All Articles