Programming for Android


In this article you will discover differences in programming for Android platform with Nitisa framework.



Code

At first lets talk about changes in code required for Android platform. We assume you are already familiar with programming with Nitisa framework. If not, please read previous articles before continue this one. In this article we only focus on differences from standard(Windows) programming.

Android is quite a poor operating system in comparison to Windows. The first difference is that the application on Android is just a library called from parent Java code. It means you can not use main and similar functions which start when application begin to work. The second difference is that on Android you have to work with already created window for you. It means you have to work with the only one predefined window. Which means you can not have more than one form.

We have tried to make the process of programming with Nitisa framework as much similar on all platforms as possible. And we think we succeeded. So, there are only three minor differences should be brought into your code to adopt it to Android platform. The first one is that you don't have to create CApplication object. The second one is that you have to use android_main function instead of main. And the last one is removing calling of Run() method of application. That is all differences in coding between Windows and Android platforms. Lets see on the example.

Android

CMyForm *form;

void android_main() // Predefined name 
{
    // No CApplication app;
    Application->CreateForm(&form);
    Application->setMainForm(form);
    // No Application->Run();
}

Windows

CMyForm *form;

void main()
{
    CApplication app;
    Application->CreateForm(&form); // or app.CreateForm 
    Application->setMainForm(form); // or app.setMainForm 
    Application->Run(); // or app.Run 
}

We also do not limit you to using only one window and one form. You may create as many of them as you wish. But only one form could be visible and draw own content at the same moment because all the forms(windows) share only one Android window(native activity).

Features

Some features available on Windows are not available when you program for Android. It is because there are no such features on Android. It means not all widgets(controls and components) will work if you add them to the form and run your project on Android device. But most of them will work of course. The widgets which certainly won't work are system dialogs. System dialogs use, as it is clear from the word "system", system/platform dependent dialog windows.

On the Android there are neither built-in fonts not API for using them. For the Android platform we have added FreeType library in dependencies to work with fonts. It means you have to add FreeType library in you application libraries. It also means that you have to add fonts to your project by your own if you want to use them in application.

The same was said about fonts is true for images as well. There is no API for working with images at this platform either. So, we have added libjpeg and libpng libraries to allow to use at least JPEG and PNG images. This means you have to add Jpeg and Png library dependencies in your application. We will extend the list of supported formats in the nearest future.

Settings

Following setting should be used when you develop an application for Android platform

  • Clang 5 or higher toolset should be used.
  • Your native activity(application) should be Dynamic Library(*.so).
  • Target API level should be 24 or higher(you may experiment with lower ones as well but please note that GLES 3.1 is required to be supported).
  • LLVM libc++ shared library should be used. Other versions are not enough fit to be used.
  • C++ exceptions should be enabled.
  • Run-Time Type Information(RTTI) should be enabled.
  • GLESv3;EGL;m;Platform;Standard;Nitisa;FreeType;Jpeg;Png;z libraries should be linked(order may be important).
  • Also don't forget to include Nitisa core and Packages directories in include paths as well as in library paths.
  • [OPTIONAL] You may also add options -Wno-unknown-pragmas -Wno-missing-braces to avoid useless compiler output.

DPI

Different monitors and screens on different devices have different DPI(dots per inch). Since release of version 4.0.0 we have added feature for easy handling such a problem. Both controls and forms have now setDPI() method for it. All you need to adjust your form to device screen DPI is to call the method in your form constructor(it actually does not matter where you place this call - before or after controls creation; it will work properly in either place). For example, in your Android application you can add following code into form constructors.

setDPI(Application->Screen->getDPI()); // Set DPI for form and all controls on it

For releases before 10.0.0 use the following code instead

setDPI(Application->getScreen()->getDPI()); // Set DPI for form and all controls on it

If you are using Nitisa framework version prior to 4.1.0 you have to use the following code instead

CApplication* app{ cast<CApplication*>(Application) }; // Get pointer to Android application instance 
Point dpi; // Declare variable to store DPI 
dpi.X = AConfiguration_getScreenWidthDp(app->getConfiguration()); // Get horizontal DPI 
dpi.Y = AConfiguration_getScreenHeightDp(app->getConfiguration()); // Get vertical DPI 
setDPI(dpi); // Set DPI for form and all controls on it

(Of course you may simplify this code and write all in just one line. The similar process could also be used on other platforms - just get DPI using platform methods and set it to form.)

All controls parameters(like borders, corner radii, paddings,...) are configured to default DPI which is { 96, 96 }. When you develop your own controls you have do the same - your control default parameters should be set for such the DPI({ 96, 96 }).

Since release of version 4.1.0 of the Nitisa framework you are allowed to design you controls at different DPIs. In this case call CControl constructor specifying the DPI you used at control design for design_dpi argument.