كيفية إنشاء تطبيق جوال متعدد المنصات في Java

هل تعلم أنه يمكنك استخدام Java لإنشاء تطبيقات جوال عبر الأنظمة الأساسية؟ نعم ، قرصة نفسك ، لقد قرأت ذلك بشكل صحيح في المرة الأولى! سأعلمك أساسيات كيفية استخدام معرفة Java الحالية الخاصة بك لإنشاء تطبيقات عالية الأداء على Android و iOS في 12 خطوة سهلة. سنفعل كل هذا باستخدام JavaFX كمجموعة أدوات واجهة المستخدم الرسومية.

لكن أولاً ، المزيد من المقدمة. ستحتاج إلى تلبية المتطلبات اللاحقة لتتمكن من إنشاء تطبيق لكل من Android و iOS. ومع ذلك ، إذا كنت لا ترغب في إنشاء تطبيق iOS ، فلا تتردد في التطوير على أي جهاز x64 بت يدعم Java SE 8. سيكون هذا المشروع عبارة عن مستودع Git مبني باستخدام gradle. لكنك لست بحاجة إلى إنشاء مستودع Git.

فيما يلي المتطلبات :

  • متوافق مع JDK 1.8 JVM
  • أدوات سطر أوامر Android (SDK الإصدار 27)
  • XCode 9.2
  • جرادل 4.2
  • Git Large File Storage (الإصدار 2.5.0) (غير ضروري إذا كنت لا ترغب في إنشاء مستودع git)
  • ويفضل أن لا يقل عن 4 جيجا رام

نافذ الصبر؟ تريد أن ترى النتيجة النهائية؟ تحقق من المشروع المكتمل أدناه.

afinlay5 / OnyxFx

مصدر Gradle كود مستودع للOnyxFx، عبر منصة (الروبوت / دائرة الرقابة الداخلية / لينكس / ماك / ويندوز) سكريبت التطبيق تقديم ... github.com

ستكون بيئة التطوير الخاصة بي هي Fedora Linux 28 و macOS High Sierra. الآن بعد أن خرجنا من هذا الطريق ، دعنا نتعمق.

1) قم بإنشاء مجلد لإيواء المشروع

استضفت مشروعي OnyxFx على النحو التالي: " / home / adriandavid / Projects / OnyxFx". أنت ، بالطبع ، حر في استضافة المشروع أينما تريد.

2) تهيئة gradle ، Git ، ضبط JAVA_HOME

افتح Terminal في جذر دليل المشروع. إذا تم تكوين gradle بشكل صحيح ، يجب أن ترى شيئًا كهذا بعد تنفيذ الأمر التالي:

gradle -v

تحتاج إلى التأكد من أن gradle يسرد تثبيت Java Development Kit (JDK) 8 المجاور للقسم المسمى "JVM".

في حين أن هناك العديد من الطرق للقيام بذلك ، فإن الطريقة الأكثر مباشرة هي التأكد من ضبط المتغير البيئي JAVA_HOME بشكل صحيح.

اعتمادًا على بيئتك ، هناك العديد من الطرق للقيام بذلك. تتمثل إحدى طرق القيام بذلك في معظم البيئات * nix في تعيين المتغير في /home//.b ash rc أو / etc / pro file. راجع دليل نظام التشغيل لديك للتأكد من ضبط متغير البيئة JAVA_HOME بشكل صحيح.

يمكنك تضمين الأسطر التالية في نهاية أي من .bashrc أو ملف التعريف لضمان ضبط JAVA_HOME بشكل صحيح.

JAVA_HOME=/home/adriandavid/java/oracle_jdk1.8.0_181/export JAVA_HOME

ملاحظة: يمكنك تثبيت Oracle's JDK 8 هنا.

بعد ذلك ، تأكد من أن الغلاف يعكس التغييرات المذكورة أعلاه عن طريق تشغيل أحد الأوامر التالية:

source ~/.bashrcsource /etc/profile

أدخل الأمر التالي للتحقق من تعيين المتغير بشكل صحيح:

echo $JAVA_HOME

إذا كنت لا تزال تواجه صعوبة أو كنت تستخدم Microsoft Windows ، فراجع هنا.

أولاً ، قم بتشغيل git initالدليل الجذر للمشروع لتهيئة مستودع Git. ملاحظة: إذا كنت لا ترغب في استضافة مستودع git ، فيمكنك تخطي هذه الخطوة.

ثانيًا ، قم بتشغيل gradle initالدليل الجذر للمشروع لتهيئة مستودع gradle. هذه الخطوة مطلوبة.

ملاحظة: ستلاحظ أن نموذجي يبدو مختلفًا بعض الشيء. هذا لأن لديّ بالفعل gradle و Git مهيئين في بيئتي المحلية.

3) كن رائع! تحرير gradle.build و

نأمل أن تساعدك الأرض والرياح والنار في أن تصبح رائعًا! قم بتشغيل محرر النصوص المفضل لديك ، وقم بتحرير build.gradle الموجود في الدليل الجذر لمشروعك واستبدل المحتويات بمحتويات GitHub التالية.

تعمل إعدادات build.gradle هذه على تهيئة مشروع gradle الخاص بنا لاستخدام المكون الإضافي javafxmobile ، وهو حصان العمل في مشروعنا. يمكنك معرفة المزيد عن البرنامج المساعد هنا وهنا. من بين العديد من الأشياء ، يقوم المكون الإضافي javafxmobile بأتمتة عملية التنزيل (من Maven Central أو jcenter) وإضافة iOS و Android SDK إلى مسار تطبيقك.

إذا كنت معتادًا على الدرج أو المخضرم أو النمل ، فهذا رائع - ربما لديك فكرة عما يحدث. إذا لم تكن معتادًا على gradle ، فلا تقلق بشأنه . كل ما تحتاج إلى فهمه هو أن gradle هي أداة بناء تُستخدم لأتمتة العديد من المهام المتضمنة في إنشاء التطبيقات مثل: الاستيلاء على التبعيات وتنظيم المشروع وما إلى ذلك.

لاحظ أننا نستهدف Android 7.1 Nougat (الإصدار 25 من API) و iOS 11 (سنرى أين يتم ذلك قريبًا). يمكنك تعديل هذه القيم كما تراه مناسبًا. لاحظ ، مع ذلك ، أنه في حالة Android ، يجب عليك التأكد من أن إصدار API يطابق إصدار SDK الذي قمت بتنزيله (المزيد حول هذا لاحقًا).

أخيرًا ، لن أعرض إنتاج ملفات تنفيذية موقعة في هذا البرنامج التعليمي. لهذا السبب ، تم تعيين iOSSkipSigning على true ولا نستخدم مهمة الإصدار Android gradle. ومع ذلك ، يمكنك توفير وسائل الراحة المناسبة لإنتاج التطبيقات الموقعة.

4) قم بإنشاء ملف جديد يسمى gradle.properties وقم بتكوينه

أنشئ ملفًا جديدًا في الدليل الجذر للمشروع يسمى gradle.propertiesوأضف المحتوى التالي إلى الملف.

robovm.device.name=iPhone-7robovm.sdk.version=11.0org.gradle.jvmargs=-Xms4g -Xmx8g

تخبر هذه الإعدادات المكون الإضافي javafxports أن يستخدم iPhone-7 كمحاكي داخلي ، لاستهداف iOS 11 ، وتمرير علامتي Xms و Xmx إلى JVM ، والتي تحدد كلاً من تجمع الذاكرة الأولي إلى 4 جيجابايت والحد الأقصى لذاكرة الكومة تجمع إلى 8 جيجابايت. سيكون هذا ضروريًا لتجميع openJDK وتطوير بنية iOS.

5) تثبيت Homebrew (iOS فقط)

إذا لم يكن لديك جهاز Mac ولا تنوي إنشاء إصدار iOS ، فلا تتردد في تخطي هذه الخطوة.

افتح Terminal في macOS والصق الأمر التالي.

/usr/bin/ruby -e "$(curl -fsSL //raw.githubusercontent.com/Homebrew/install/master/install)"

6) قم بتثبيت مقبس USB Multiplexing Socket (iOS فقط)

انتقل إلى هذه الخطوة فقط إذا تم تثبيت Homebrew بنجاح. إذا لم يكن لديك جهاز Mac ولا تنوي إنشاء إصدار iOS ، فلا تتردد في تخطي هذه الخطوة.

افتح Terminal في macOS والصق الأمر التالي.

brew install usbmuxd

7) احصل على أدوات سطر أوامر Android

Grab Android Command Line Tools for your platform here. After the download has finished, unzip the folder and paste the contents in the directory of your choice. For me, this was /home//Android.

8) Set Android_HOME, Grab necessary Android packages

As with Java, gradle needs to know where to look to find the Android Command Line Tools. There are a few ways to do this. However, in the spirit of simplicity and consistency, we will set the ANDROID_HOME environmental variable in this tutorial. Add the following variable in the same way that we did it for JAVA_HOME. For example:

ANDROID_HOME=/home/adriandavid/Android/ export ANDROID_HOME

Remember to reload the shell by adding source le> as we did for JAVA_HOME.

Now, grab the tools necessary to build the Android build. Execute the following command:

# *.nix./sdkmanager "platform-tools" "build-tools;25.0.3" "platforms;android-25" "extras;android;m2repository" "extras;google;m2repository"
or
#Windowssdkmanager "platform-tools" "build-tools;25.0.3" "platforms;android-25" "extras;android;m2repository" "extras;google;m2repository"

Take careful notice that the SDK and API version we have specified in gradle.build correspond to the version we have specified in this command. Namely, “25”. Should this be misaligned, the build will not succeed.

9) Create the application’s directory structure

To automate the process of creating these directories, execute the following shell script.

Bourne-Again Shell / Korn Shell:

Windows Shell (cmd):

Save the file as mkpdir.bat or mkpdir.sh and execute the file from the project’s root directory as root (or Administrator).

# *.nixchmod +x mkdir.sh-sh ./mkpdir.sh
# Windowsmkpdir

Notice that we created directories for embedded and desktop. We will produce a desktop build, because it takes no additional work to do so. However, we will not produce any builds for embedded devices.

10) Create your JavaFX Application!

Navigate to /src//java and begin developing your JavaFx application! Application resources are stored in /src//resources.

You can start with a simple Hello World application or look at the source code that I have put together here. OnyxFx is an application I made, following these instructions, that makes REST calls over HTTP to the OnyxFxAPI. The API, in turn, is a web scraper that will return the statistical data (points per game, rebounds per game, assists per game) for the NBA® player and season the client specifies. It returns the data as JSON, which is then parsed and displayed to the screen of the mobile app. Feel free to edit it!

Keep in mind that although you can share source code, you should include custom edits in each copy of the source, should you want to make device specific changes.

Also note that the underlying compiler (MobiDevelop’s fork of RoboVM) does not fully support all Java 8 APIs. If you look very closely at my source code, you will notice that in the iOS version of the source code, I have removed unsupported API such as java.util.function.BiConsumer and java.util.Map.replace().

11) Create a RAM disk for iOS builds (iOS only)

The compilation process for iOS is very resource-heavy, as the plugin will compile the entire openJDK and other libraries twice to create a fat JAR that it will use to build your application. Therefore, you should preemptively create a RAM disk to accommodate for the memory requirements.

This step, however, is subject to your judgement of your machine’s capabilities. For context, the macOS machine that I used to compile my iOS app has 4GB of DDR2 RAM. I decided to make an 8GB RAM disk. To do so, execute the following command in the terminal.

SIZE=8192 ; diskutil erasevolume HFS+ ‘RoboVM RAM Disk’ `hdiutil attach -nomount ram://$((SIZE * 8192))`

12) Build and Run your application!

To build your application, execute the gradle wrapper in the root directory from the terminal as follows.

./gradlew clean build

This will produce a desktop application packaged as a JAR with scripts to run the application provided in /build/distributions/ ar> ; and /build/distributions/ Name.zip>. Should you unzip the directories, you will notice the following structure:

Notice that in /bin there are scripts to execute the application. These scripts rely on preserving the current folder structure. Also notice that is not necessary for you to have tree installed. It is used here simply for illustrative purposes.

There is, additionally, a standalone JAR that you can use to execute the application on any desktop environment supporting JavaFX 8. To run the application, execute one of the following:

# Navigate to /build/distributions//
#On *.nixcd bin./
#On Windowscd bin
#Platform agnosticjava -jar OnyxFxMobile.jar (or double click, if jvm is configured to run .jar files)
Note: If the executable providing "java" is not the same vendor and/or version of the Java 8 JDK with which you built this application, the jar may not run. JavaFX 8 builds between the openJDK & Oracle JDK are incompatible.
Otherwise: /location/to/java8/bin/java -jar 

View this project’s gradle tasks

You can view this project’s gradle tasks by running the following in the project’s root directory.

./gradlew tasks

To Compile, Run on Desktop

The following command will run your project in the host environment.

./gradlew jar./gradlew run

You will find a standalone jar in build/libs/ t;.jar .

To Compile, Run on Android

./android #Generates a debug Android apk containing the JavaFX application.
./androidInstall #Launch the application on a connected android device.
./androidRelease #Generates a release Android apk containing the JavaFX application.
Note: You will need to configure a valid signingConfig when releasing an APK (javafxports).

You will find two APKs in build/javafxports/android.

The first will be named t;.apk.

The second will be named -unaligned.apk.

To Compile, Run on iOS

./createIpa - Generates an iOS ipa containing the JavaFX app.
./launchIOSDevice - Launches app on a connected ios device.
./launchIPadSimulator - Launches app on an iPad simulator.
./launchIPhoneSimulator - Launches app on an iPhone simulator.

You will find three executables in build/javafxports/ios.

The first will be named t;.ipa.

The second will be named ame>.dSYM.

The third will be named <AppName>.app.

Some screenshots of my sample app

On Desktop

On Android

On iPhone

On iPad

Splash Screen

My Closing Thoughts

javafxports is a promising project that aims to bring JavaFX and the Java SE platform onto mobile and other devices. In a way, the tool parallels Xamarin in its efforts. However, the project has a lot of work left to be done.

For a start, the plugin currently does not fully support Java 8. On Android, it uses retrolambda to handle Java 8 Lambda Expressions & Method References. It technically is up to Java 6. Additional dependencies make it such that you can use Java 8. However, the process is straightforward, the builds work as expected, and the compilation time is not too long.

On iOS, however, the builds are extremely memory-intensive and the compilation process takes a very long time. The following is a snippet of the log for ./gradlew createIpa task.

:createIpa (Thread[Task worker for ‘:’,5,main]) completed. Took 1 hrs 46 mins 40.198 secs.

In total, the process consumed about over 6GB of RAM on my machine. This is hardly ideal. However, the future is promising. A company called Gluon has developed a high performance, fully modular custom JVM fully supporting Java 9, that you can read more about here.

This article is originally published on the blog section of my homepage, here.

Resources to explore:

  • JavaFxMobile Plugin Git Repo: //github.com/javafxports/javafxmobile-plugin
  • JavaFxPorts Documentation: //docs.gluonhq.com/javafxports/#_how_it_works
  • JavaFxPorts Homepage: //javafxports.org/
  • Gluon Documentation: //gluonhq.com/developers/documentation/
  • Google Groups Page for JavaFxPorts: //groups.google.com/forum/#!forum/javafxports
  • StackOverflow Page for JavaFxPorts: //stackoverflow.com/questions/tagged/javafxports
  • Gluon Mobile Pricing/License Options: //gluonhq.com/products/mobile/buy/