I thought I should at least take a look at the amazing Android support in XE5 so I decided to work through the tutorial that was brought to my attention recently. The first order of business of course, is getting installed.
After making a cup of tea, reading a book, doing some housework and making a start on Part 4 of my series of Oxygene for Android camera articles while XE5 installed (not an exaggeration), the first order of business was sorting out the botched install.
This might have been caused by the fact that during the installation I opted to use my existing installation of the Android SDK and only install the NDK, which I didn’t already have (I’ve not needed it for Android development, until now). The installer explicitly gave me this option, and it seemed to make sense since my SDK install was working perfectly well for me. But upon completion of the install neither of the paths to the SDK or the NDK were configured in the Delphi IDE.
I might have expected the SDK folder to be missing, since I didn’t ask the installer to, well, install it. But the NDK was installed by the XE5 installer so this really should have been setup for me, no?
Given that things were already clearly not going to work “out of the box” I decided to take the opportunity to have my NDK setup consistent with my SDK and moved the installed folder to sit alongside the existing SDK.
After specifying these base SDK and NDK paths things still weren’t quite settled. The configuration wizard then complained about the platforms folder (one of the plethora of sub-paths that need to be set for some reason), which I had to manually correct. No biggy.
At last the IDE seemed happy.
Before jumping in to the tutorial itself, I thought I would try and get an answer to one of the questions that have been steadfastly ignored: Where and how to set permissions and hardware feature dependencies.
I found that application permissions are set in Project Options and the reason they aren’t mentioned in the tutorial is that the ones required by that tutorial (and more!) are all on by default. Which is great if you are writing an app that needs coarse and fine location, to use the camera, read phone state, read and write to the calendar (!?) and read and write storage. If not, you’ll have to remember to turn these off to avoid potential customers wondering why your app needs these things when it clearly doesn’t.
There are pages and pages of permissions to wade through, checking the state of individual checkboxes on each one. There is no concise summary of the permissions you have enabled, just this productivity killing checkbox list overkill of which the Delphi IDE developers seem to have become so enamored in recent releases.
I don’t know whether this checkbox list is platform independent or whether changes to permissions in one platform are automatically applied to the corresponding permissions on other target platforms as he permissions list for the iOS platform was entirely empty, presumably because I had not yet setup an iOS environment for XE5.
Project Options relating to dependency on hardware features do not seem to exist.
Looking for the file I knew was involved (the AndroidManifest) I found one in the build output folder of my project. I deduced that editing this file is no good since it is overwritten by the build process.
Then I noticed the AndroidManifest-template file in the project folder. It’s not listed in the Project Explorer that I could see. But having stumbled across it I divined that I could edit this file to add a hardware dependency which then found it’s way into the AndroidManifest XML as part of the build process.
This was almost identical to the process required in Oxygene except with Oxygene you are simply directly editing the Manifest, not a template fed into a build process. And with Delphi there is no code completion support when editing the template file, perhaps in part because the formatting required for the template results in it not being valid XML. But whatever the reason, the “high productivity” support in this IDE are not to be found in this area and far from being an improvement over Oxygene, or other development tools, it’s not even as good as any half decent XML editor would provide (being an invalid XML file, even using a proper XML editor wouldn’t have helped I don’t think).
But, I have all the permissions I need (and some that I don’t) so it’s time to build this amazing app.
Trying to build succeeded only in getting a cacophony of complaints from the linker:
This all seems to start with a file that cannot be found, specifically:
Which is very odd, because it is quite plainly where it should be:
From a bit of Googling I gather that this appears to have been quite a common problem at least with older revisions of the NDK, though none of the proposed solutions made much sense since none of them related to the Delphi use of the NDK – obviously. The ones that did make sense didn’t help.
However, the issue in my case was quite simple.
Delphi doesn’t appear to support UNC paths for SDK/NDK locations.
Don’t Use UNC Path For SDK/NDK Locations
The UNC path in this case allows me to conveniently share an installation of the SDK/NDK maintained on my host Mac between all my VM’s (and, by virtue of using a cloud synced folder – in this case Google Drive – also shared with other synced computers)
But using a UNC path in Delphi doesn’t work.
I found this only by trial and error. Oxygene must have some more sophisticated file handling technology not available to the Embarcadero developers because this causes no problem for that tool. Perhaps some important information about not using UNC paths was in the “Getting Started for Android” video presented on the Delphi XE5 start page ?
At this point I didn’t know since the IDE provided no way for me to view that video due to the lack of Flash or HTML5 video support in the embedded browser.
I do all my web browsing on the Mac host so I don’t bother maintaining an up-to-date browser in my VM that I don’t need.
Wouldn’t it be a good idea to provide an accessible link to the video in question to cover this sort of situation ? Then users wouldn’t have had to go digging through the HTML source for the start page to find it. But go digging I did and found the link to the youtube video. Luckily my internet connection was up, so I was able to watch the video but it turns out that there was no mention of UNC path problems anyway. Hey ho.
It was indeed fortunate that my intuited solution turned out to be correct or this could have taken up more time than it already had.
Although the UNC path is convenient since it is certain to be the same in all my VM’s, each VM also has a drive mapped to the \\psf\home volume so I just changed the paths to use the drive mapped path appropriate for this VM and the problem was solved.
I could build.
But I couldn’t run of course, since FireMonkey isn’t supported on my device and I had better things to do than deal with the cumbersome emulator support.
It’s so much easier when you can use an Android development tool with all Android resources natively, such as debugging in an x86 VM or running on any Android device that meets the needs of your application without the demands of a hefty runtime to also support.
It makes developing apps so much faster. 😉
For me though, this was the practical end of my first look at Delphi for Android.
I was able to obtain one further interesting fact at this point however.
HOW Big ?!
Another question that has been determinedly ignored is that of the size of the executables produced by Delphi for mobile devices. For Android at least I can now find this out for myself.
An “Empty App” project in Delphi XE5 compiles to a debug build of an SO file that is 48 MB in size.
The Java stub that is wrapped around this to form the APK “envelope” might add a little more.
Update: Having now set up an emulator and deployed a debug build to that, I find that far from growing, the actual APK seems to shrink and on the (emulated) device is reported as 24.4 MB.
You might want to go back and read that again. It’s not a typo. 24.4 MEGABYTES
For what is not even a Hello World app.
By contrast the debug build of my camera app in Oxygene compiles to an apk of a whopping 48 KB. That also is not a typo: 48 KILOBYTES.
An app that does something useful which is 3 orders of magnitude smaller than an app that does literally nothing.
Does anyone else remember when Delphi could hold it’s head up high and rightly claim that it had no runtime dependencies other than the OS itself ? VBRUNx00.DLL was a source of great amusement. With FireMonkey not only is there a whopping great runtime engine, but you aren’t even able to share it (the standby defence of the beleaguered VB developer back in the day) between multiple FireMonkey applications on the same device.
Every FireMonkey app essentially comes with an embedded FMRUNx00.DLL
Oh how the mighty are fallen.
Size DOES Matter
Although time has marched on and such file sizes are not really significant for desktop applications, in the mobile device world size is important.
Both Google and Apple stores have limits on maximum executable file size.
In the case of Google you are limited to 50MB plus additional download packages which can be up to 4GB. But your executable must be under the 50MB limit.
In the case of Apple, your application executable is limited to 60 MB. In addition, if it is over 50MB users/customers will only be able to download it over wi-fi. If they are on a mobile data connection and your app is bigger than 50MB they are likely to just choose someone else’s, smaller app.
Of course, 24 MB is the debug build. A release build is smaller.
Much smaller. The unsigned APK is just still 21.49 MB in size. So only 2 orders of magnitude bigger than the debug build of a functioning camera app.
5 MB for an app that doesn’t do anything is perhaps a bit better, but how quickly does that grow as you add capability ?
Update: There is clearly something odd going on. Since I posed my original findings, based on looking at build products, I received comments suggesting different figures. I repeated my simple builds, deploying the resulting APK’s to an emulated device and found starkly different sizes were reported by the emulated device than the size of the build products would have suggested. The debug build was half the size, but the release build was now not much smaller than the debug build. I am also told that others have started to voice concerns about application size in the Embarcadero forums, so there is an issue. Reliably quantifying it is proving elusive. Which is itself something of an issue.
In the meantime, this makes the size of an actual, released app, as reported by the Google Play store perhaps our only reliable indicator so far.
The iWD app that Embarcadero are showing off in the Play store initially weighed in at 10 MB. After a handful of bug fixes and tweaks it has now grown to 12 MB.
Store app size limits are increased from time to time, but not very often and not – historically – by much. Only time will tell whether FireMonkey apps will reach a level of functionality where their size becomes problematic in this respect.
Another is that if you are hoping to win impulse customers purchasing your app, even only relatively hefty downloads is a potential obstacle.
First impressions last, as they say.
This has to be one of the worst first impressions experiences with Delphi since… well… ever.