{"id":1744,"date":"2013-09-22T17:43:52","date_gmt":"2013-09-22T05:43:52","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=1744"},"modified":"2013-09-22T17:43:52","modified_gmt":"2013-09-22T05:43:52","slug":"apkudo-kudos-and-non-functional-quality","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/1744\/","title":{"rendered":"Apkudo Kudos and Non-Functional Quality"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">5<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p><a href=\"http:\/\/delphi.org\/2013\/09\/delphi-xe5-android-device-compatibility\/\">Jim McKeeth recently blogged about the results<\/a> of submitting an &#8220;empty&#8221; FireMonkey app to the <a href=\"https:\/\/www.apkudo.com\/\">apkudo online Android testing service<\/a>.<\/p>\n<p><!--more--><\/p>\n<p>Jim reports that an &#8220;empty&#8221; FireMonkey app failed on only 13 devices out of 118, claiming an impressive 89% success rate.<\/p>\n<p>It made me curious to see what the same exercise with Oxygene would yield.<\/p>\n<figure id=\"attachment_1745\" aria-describedby=\"caption-attachment-1745\" style=\"width: 313px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-09-22-at-15.44.04-.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-09-22-at-15.44.04-.png?resize=313%2C254&#038;ssl=1\" alt=\"242 \/ 248 - not bad at all\" width=\"313\" height=\"254\" class=\"size-full wp-image-1745\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-09-22-at-15.44.04-.png?w=313&amp;ssl=1 313w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-09-22-at-15.44.04-.png?resize=300%2C243&amp;ssl=1 300w\" sizes=\"(max-width: 313px) 100vw, 313px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-1745\" class=\"wp-caption-text\">242 \/ 248 &#8211; not bad at all<\/figcaption><\/figure>\n<p>Just in case that graphic isn&#8217;t clear:  That&#8217;s just 3 failures from 248 tested.  3 results appear to have gone missing (3 successes + 242 failures = 245, not 248), but if we assume those missing results were also failures then we get a success rate of<strong> 97.5 %<\/strong> of the available devices.  Not bad at all.<\/p>\n<p>If we apply the same criteria to Jim&#8217;s FireMonkey results, the success rate doesn&#8217;t look as good as it first did.  Although Jim explains that some devices were excluded by the runtime requirements of FireMonkey he chooses not to say how many devices that was.  But let&#8217;s assume it was the same 248 devices that were available for my test.<\/p>\n<p>With 105 successes and 248 devices, the comparable FireMonkey success falls from 89% to just <strong>42.3 %<\/strong>.<\/p>\n<p>You can of course spin these numbers however you wish to fit a particular desired story, as we have seen &#8211; you can, for example, more than double a 42% success rate into 89% !<\/p>\n<p>But sometimes such manipulations are a bit too obvious to be ignored, so rather than thinking too much about how to interpret such results Embarcadero would prefer you not to think in those terms at all.<\/p>\n<p>It&#8217;s all a bit ironic really, considering that they keep trying to find statistics that make a point that they simultaneously insist is irrelevant.<\/p>\n<p>No, they would much prefer that instead of worrying about all the Android devices your apps will <em>not<\/em> work on, that instead you think about all the iOS devices that it <em>will<\/em> (and again, kindly ignore those iOS devices that it won&#8217;t).<\/p>\n<p>In fact, Jim says exactly that:<\/p>\n<blockquote><p>Instead of focusing on the small percentage of Android devices you are missing with Delphi XE5, I\u2019d instead invite you to consider the millions of iOS devices you can target from the same code base. Including iOS 7!<\/p><\/blockquote>\n<p>Note the not-so-subtle attempt to plant firmly in our minds the belief that the failures are only a &#8220;small percentage&#8221; (again: &#8220;<em>please don&#8217;t think about this, just take our word on it<\/em>&#8220;) there is a problem with encouraging this sort of thinking.<\/p>\n<h3>Non-Functional Quality<\/h3>\n<p>Whilst it sounds attractive to a developer to contemplate the total population of different devices they can compile their app for from &#8220;a single codebase&#8221;, this is not a feature that can be sold to potential users &#8211; i.e. customers.<\/p>\n<p>It is a &#8220;non-functional quality&#8221;, to borrow a term from <a href=\"http:\/\/blogs.embarcadero.com\/vsevolodleonov\/2013\/09\/19\/are-you-asking-about-app-size-by-delphi-for-android\/\">another post by a different Embarcadero employee<\/a>, dismissing concerns about application size as just such a &#8220;non-functional quality&#8221; (in that case utterly failing to address the very real concerns that app-bloat can lead to in the mobile space).<\/p>\n<p>Odd that a non-functional quality is dismissed (incorrectly imho) on the one hand and yet a different non-functional quality offered as a &#8220;feature&#8221; on the other.<\/p>\n<p>It is not of course entirely an irrelevant point.  Although a non-functional quality, the cost of development <em>is<\/em> a factor.  And I am sure everyone is <em>very<\/em> grateful to Embarcadero for keeping their customers development costs to a minimum.<\/p>\n<p>But having a cost-effective, multi-device platform is no guarantee of success.  No matter how attractive the development environment to the developer, users do not choose applications on the basis of such considerations.<\/p>\n<p>The fact that an Android app also runs on iOS is of no interest to the vast majority of Android users nor vice versa for iOS users.<\/p>\n<p>The fact that an Android or Cocoa app does not &#8211; and perhaps cannot &#8211; support all of the features that the particular platform provides for on the other hand, or that an app doesn&#8217;t feel like it really quite &#8220;fits&#8221;&#8230; such things <strong>will<\/strong> be a concern.<\/p>\n<p>As developers, we should be concerned not with what it is possible for us to do in some idealised, code writing vacuum, but what our users need and want us to do for <em>them<\/em>.<\/p>\n<h3>Concrete Examples<\/h3>\n<p>I am by no means an experienced Android developer but even I can already see areas where FireMonkey faces some serious &#8211; possibly insurmountable &#8211; difficulties, at least on the Android platform.  These, or similar, quite possibly on iOS too.<\/p>\n<p>I just posted the final instalment in my camera app series using Oxygene.  In this final part I added support for an intent filter.<\/p>\n<p>Implementing the behaviours required goes far beyond simply styling some UI elements.  Your code is required to interact directly with the object model of the application.  In even a simple case such as presented by my camera app, a FireMonkey implementation will involve some really not very pleasant JNI code.<\/p>\n<p>And in a more complex scenario &#8211; implementing multiple activities where one is the entry point for an intent, separate from your main activity &#8211; as far as I can see, it is currently impossible and will require some additional infrastructure support in the FireMonkey runtime, if this is even possible at all within the constraints imposed on an NDK based application.<\/p>\n<p>Similarly, Android widgets &#8211; currently not just difficult but simply impossible, as far as I can determine, using FireMonkey.<\/p>\n<p>If this is mistaken and these things are possible, I would be most interested to see some examples.<\/p>\n<p>Of course, Embarcadero are perfectly correct.  An application that doesn&#8217;t implement these things will run perfectly well without them on iOS as well as Android, and perhaps this additional non-feature will be enough to make up for the lack of real features.<\/p>\n<h3>Full Disclosure<\/h3>\n<p>I also submitted my camera app to <strong>apkudo<\/strong> with some disturbing results.  It fails on all but 4 devices.  Ouch!  \ud83d\ude41<\/p>\n<p>The vast majority of failures were the result of my app explicitly requiring Android 3.0 or above (for the ActionBar UI).  Everything pre-Android 3.0 is excluded by this decision.  Of course, I can implement ActionBar support for earlier devices (down to 2.1) if I wanted to, and even older than that if I provide an alternate, non-ActionBar UI within the app.  It&#8217;s up to me.  There are no minimum requirements imposed on me.<\/p>\n<p>But currently as a consequence of the self-imposed Android 3.0 requirement, only 32 of the testable devices are supported.  I knew perfectly well that I was taking a rather cavalier attitude to compatibility concerns, focussing on an app that worked on my particular device.<\/p>\n<p>But 4 \/ 32 is still pretty horrifying and a little disappointing. \ud83d\ude41<\/p>\n<p>On the bright side, this is something I can fix if were minded to, and provides an opportunity for me to learn some more lessons about developing for Android which will stand me in good stead for the future.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">5<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> Jim McKeeth recently blogged about the results of submitting an &#8220;empty&#8221; FireMonkey app to the apkudo online Android testing service.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4,207],"tags":[222,292,135],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-s8","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":735,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/735\/","url_meta":{"origin":1744,"position":0},"title":"RAD STUDIO XE2: Launch Event Report","date":"04 Aug 2011","format":false,"excerpt":"Today I was fortunate to be present in Auckland at the World Premier of the launch event for RAD Studio XE2. \u00a0There is so much good to report that I really don't know where to begin, so apologies if this post is a bit of a disorganised ramble. \u00a0But here\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2104,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2104\/","url_meta":{"origin":1744,"position":1},"title":"Delphi for Android Supports Android!","date":"07 Nov 2013","format":false,"excerpt":"Jim McKeeth is getting all excited about being able to develop for Google Glass using Delphi XE5. I'm pleased for him, I really am. It must be a huge relief that Delphi for Android can actually target this Android device. Of course, the very fact that there was any doubt\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":791,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/791\/","url_meta":{"origin":1744,"position":2},"title":"Why Does My OSX FireMonkey App Think It Is a Console App ?","date":"15 Sep 2011","format":false,"excerpt":"Because System.IsConsole is hardwired to TRUE on MAC OS: This is actually also the case for $ifdef LINUX, but nobody is likely to notice that, at least not just yet. :) But it caused me no end of confusion when my FireMonkey app behaved one way on Windows and a\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1587,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1587\/","url_meta":{"origin":1744,"position":3},"title":"Delphi for (Some) Android","date":"13 Sep 2013","format":false,"excerpt":"Embarcadero have blogged about the first Android app \"in the wild\" (actually, being on the Play store I think it's the first domesticated app - wild ones surely get side-loaded ? :)). Rather embarrassingly they already have a comment from someone unable to use this \"true native Android\" application on\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1068,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1068\/","url_meta":{"origin":1744,"position":4},"title":"Info From the World Tour (Hamburg)","date":"22 Aug 2012","format":false,"excerpt":"In the Embarcadero forums, Roland Kossow posted his report on the first of the \"RAD Studio World Tour\" events in Hamburg yesterday, reporting on what's new in XE3 and adding some more detail to the \"XE3 And Beyond\" blog post. In a nutshell we have \"FM2\" (FireMonkey 2 - no\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":892,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/892\/","url_meta":{"origin":1744,"position":5},"title":"Poll: FireMonkey or &#8220;Platform Native&#8221; ?","date":"07 Jun 2012","format":false,"excerpt":"We have had almost a year of monkeying with fire now - enough time I think for people to have formed a view as to whether it is truly a viable multi-platform framework for the future, or just a convenient cross-platform solution with limited, genuine utility. At the same time,\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1744"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=1744"}],"version-history":[{"count":9,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1744\/revisions"}],"predecessor-version":[{"id":1754,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1744\/revisions\/1754"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=1744"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=1744"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=1744"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}