WELKE MEERWAARDE BIEDT KOTLIN AAN DE ONTWIKKELAAR BIJ HET MAKEN VAN ANDROIDAPPLICATIES? PROMOTOR: MH STIJN WALCARIUS ONDERZOEKSVRAAG UITGEVOERD DOOR KRISTOF COLPAERT VOOR HET BEHALEN VAN DE GRAAD VAN BACHELOR IN DE NEW MEDIA AND COMMUNICATION TECHNOLOGY HOWEST | 2015 - 2016 WELKE MEERWAARDE BIEDT KOTLIN AAN DE ONTWIKKELAAR BIJ HET MAKEN VAN ANDROIDAPPLICATIES? PROMOTOR: MH STIJN WALCARIUS ONDERZOEKSVRAAG UITGEVOERD DOOR KRISTOF COLPAERT VOOR HET BEHALEN VAN DE GRAAD VAN BACHELOR IN DE NEW MEDIA AND COMMUNICATION TECHNOLOGY HOWEST | 2015 - 2016 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Voorwoord Deze bachelorproef is het sluitstuk van mijn opleiding New Media and Communication Technology aan de Hogeschool West-Vlaanderen. Ze weerspiegelt de interesses en passies die ik voor, tijdens en na de lessen heb ontwikkeld en sluit ook voor een groot deel aan bij het onderwerp van mijn stage bij In The Pocket. Graag bedank ik iedereen die me heeft geholpen gedurende deze periode. Mijn ouders en vriendin, Lieve Balcaen, om het werk na te lezen op schrijf- en tikfouten. Stijn Walcarius, mijn bachelorproefbegeleider, voor de inhoudelijke feedback en de snelle en gerichte antwoorden op mijn e-mails van de voorbije weken. Iedereen die mij, hetzij rechtstreeks, hetzij onrechtstreeks heeft geholpen. Ten slotte wil ik ook mijn stagebedrijf, In The Pocket, bedanken, voor de kansen die het mij biedt. Veel leesplezier! 4 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Abstract Mobiele toestellen en de daarbij behorende applicaties zijn booming en daardoor niet meer weg te denken uit de moderne IT-wereld. Android ontpopt zich daarin als een van de populairste platforms, mede door zijn brede mogelijkheden en gebruiksvriendelijke karakter. Dat laatste kan moeilijk gezegd worden van de ontwikkelingsbasis die Google, de maker van Android, aanbiedt aan de developers. Die is namelijk gebaseerd op een verouderd framework en gebruikt vaak een al te complexe syntax. Het ontbreken van een zicht op onmiddellijke verbetering, laat de deur open voor alternatieven zoals Kotlin. Die programmeertaal werd ontwikkeld door JetBrains en bevindt zich op dit moment nog in een vroeg stadium. Net daarom blijkt het een interessant topic voor verder onderzoek in deze bachelorproef. Kotlin is een taal die gecompileerd wordt naar geldige Java bytecode en die daardoor geschikt is voor de ontwikkeling van Android-applicaties. Haar belangrijkste pijlers zijn veiligheid voor null-fouten, volledige interoperabiliteit met Java, een beknopte en expressieve schrijfstijl en openheid naar de developers. Hoewel de syntax grote gelijkenissen vertoont met die van Java, zijn er ook een aantal belangrijke verschilpunten. Zo zijn variabelen bij voorkeur onveranderlijk, een keuze die is ingegeven door het inbouwen van een veiligheid tegen null-fouten. Methodes en functies kunnen los van klassen genoteerd worden, en externe klassen kunnen uitgebreid worden met eigen toevoegingen. De primaire constructor van een klasse wordt opgenomen in de declaratie ervan, terwijl de secundaire, net zoals bij Java, in de body worden genoteerd. Kotlin voorziet ook een verkorte schrijfwijze voor singletons en klassen die enkel data bijhouden. Lambda-expressies laten toe om functies als waarden te behandelen, waardoor ze als argument van andere functies kunnen worden gebruikt. Checked exceptions en primitieve datatypes zijn niet aanwezig in Kotlin. JetBrains voorziet naast de taal ook een bibliotheek met Kotlin-uitbreidingen die specifiek gericht zijn op Android. Anko is in de eerste plaats een domeinspecifieke taal die het programmatorisch beschrijven van lay-outs op een andere manier wil benaderen. Verder biedt de bibliotheek ook alternatieven voor het ondervragen van de interne SQLite-databases en het uitvoeren van asynchrone taken. De voordelen van Kotlin en Anko situeren zich in het productiviteitsgebied: het programmeren van applicaties vraagt minder syntax en is daardoor eenvoudiger. Verder is de leercurve laag, en zijn de integratie en wisselwerking met Android Studio en het standaardframework nagenoeg perfect. Toch zijn er ook nadelen verbonden aan de taal en zijn gereedschappen: de null-veiligheid kan niet gegarandeerd worden in communicatie met Java, de community is klein en de kinderziekten zijn nog niet helemaal weggewerkt. Bovendien brengt het gebruik ervan, zo blijkt uit een eigen praktijkvoorbeeld, langere buildtijden en grotere packages met zich mee. Het eindoordeel leert dat de voordelen van Kotlin voor Android-ontwikkelaars buiten kijf staan. Niettemin blijft de keuze voor de taal bovenal individueel, projectafhankelijk en genuanceerd. 5 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Figuren- en tabellenlijst Figuur 1: Verdeling van de Android-versies in maart 2016. Figuur 2: Methodeverdeling tussen een reeks veelgebruikte Android-bibliotheken. Figuur 3: Schematische voorstelling van het buildproces in Kotlin. Figuur 4: Notatie van een variabele in Kotlin. Figuur 5: Notatie van een functie in Kotlin. Figuur 6: Notatie van een lambda-expressie in Kotlin. Figuur 7: Notatie van een member reference in Kotlin. Figuur 8: Visibility modifiers in Java. Figuur 9: Visibility modifiers in Kotlin. Figuur 10: Voorbeeld van een Anko-layout. Figuur 11: Vergelijking van het aantal methodes tussen Kotlin en andere alternatieve Java-talen. Figuur 12: Screenshots van de Android- en Kotlin-praktijkapplicaties. Figuur 13: Vergelijking van buildtijden in Android en Kotlin bij de vooraf gedefinieerde milestones. Figuur 14: Vergelijking van het aantal lijnen code in Android en Kotlin. Figuur 15: Vergelijking van de grootte van het APK-bestand in Android en Kotlin. Figuur 16: Vergelijking van het aantal methodes in Android en Kotlin. 6 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Lijst met afkortingen APK-bestand Een uitvoerbaar bestand voor het installeren van een Android-applicatie op een device (Gordon, 2015). API Voluit ‘Application Programming Interface’. Een reeks gereedschappen die door een bepaalde applicatie worden aangeleverd voor communicatie met een andere applicatie (“Application programming interface”, s.d.). DEX-limiet Android compileert de code van een applicatie naar een Dalvik Executable (DEX) met bytecode-instructies die de Dalvik Virtual Machine (tot Android 4.4) of de Android Runtime (vanaf Android 5.0) kunnen uitvoeren (“Glossary”, s.d.). Dit DEX-bestand kan maximaal 65.563 methodes bevatten. IDE Voluit ‘Integrated Develop Environment’. Dit is een ontwikkelomgeving met gereedschappen die de ontwikkelaar helpt bij het schrijven van applicaties. JAR Staat voor ‘Java Archive’. Het is het standaard archiefformaat voor gecompileerde Java bytecode-bestanden (“JAR”, s.d.). JSON Voluit ‘JavaScript Object Notation’. Het is een universele manier om data op een gestructureerde wijze voor te stellen (Lengstorf, 2009). Het wordt daartoe vaak gebruikt voor het uitwisselen van gegevens tussen verschillende applicaties. ORM Voluit ‘Object Relation Mapper’. Het is een bibliotheek of techniek die toelaat om informatie die gestockeerd is in een database, op een objectgeoriënteerde manier te benaderen (“What is an ORM”, s.d.). SDK Voluit ‘Software Development Kit’. Een verzameling van gereedschappen die bruikbaar kunnen zijn bij het ontwikkelen van applicaties voor een bepaald besturingssysteem (“Software development kit”, s.d.). UI Voluit ‘userinterface’, de visuele gebruikersomgeving. 7 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Verklarende woordenlijst Android Runtime De opvolger van de Dalvik Virtual Machine, voor versies van het besturingssysteem die nieuwer zijn dan Android 5.0. Anonieme klasse Een klasse die bij het declareren ook meteen geïnstantieerd wordt. Ze krijgt geen naam en kan bijgevolg geen tweede keer gebruikt worden (“Anonymous Classes”, s.d.). Boilerplate code Code die veelvuldig en zonder grote wijzigingen herhaald wordt binnen een project. Build system Verzamelnaam voor een reeks gereedschappen die het builden, testen, uitvoeren en verpakken van applicaties automatiseren en vereenvoudigen (“Build System Overview”, s.d.). Casting Het omzetten van een waarde met een bepaald datatype naar een waarde met een ander datatype. Compiler Een compiler is een programma dat syntax die geschreven is in een bepaalde programmeertaal, omzet naar equivalente syntax in een andere taal (“Compiler”, s.d.). Aangezien de Dalvik Virtual Machine of Android Runtime niet rechtstreeks overweg kunnen met de door ontwikkelaars geschreven Java-syntax, wordt die code gecompileerd naar complexere bytecode, die zij wel verstaan. Constructor Methode die een nieuwe instantie van een klasse een initiële configuratie geeft. Dalvik Virtual Machine De variant van de Java Virtual Machine voor mobiele toestellen. Vertaalt de applicaties naar machinecode die rechtstreeks door de processor kan worden uitgevoerd en verzorgt het geheugenbeheer. Developer Het begrip ‘developer’ kan vrij vertaald worden als ‘ontwikkelaar’. Het is een persoon die software creëert. Event Is een actie of gebeurtenis die de applicatie kan detecteren en desgewenst ook kan afhandelen (“Event (computing)”, s.d.). Exception Een event dat plaatsvindt tijdens het uitvoeren van een applicatie en dat de normale werking ervan verstoort (“What Is an Exception?”, s.d.). 8 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Field Een variabele die een waarde bijhoudt (primitief datatype) of een referentie naar een waarde bevat (referentietype). Fields worden in het objectgeoriënteerd programmeren typisch privaat gehouden binnen de klasse (“What is the difference”, s.d.). Framework Een softwareframework is een verzameling van componenten die gebruikt kunnen worden bij het programmeren van applicaties (“Framework”, s.d.). Functioneel programmeren Een vorm van programmeren waarbij maximaal wordt gebruikgemaakt van functies. Deze functies vertonen bovendien geen neveneffecten die de status van variabelen erbuiten wijzigen (“Functioneel programmeren”, s.d.). Getters Laten toe om de waarde van een privaat field van buitenaf op te vragen. Imperatief programmeren Een programmeervorm waarbij iedere stap van de applicatie een taak voorstelt die uitgevoerd moet worden door het toestel (Paulsen, 2015). Inference Het proces waarbij de compiler het datatype van een variabele afleidt uit zijn waarde. Het datatype moet dus niet meer expliciet aangegeven worden. Intent Een Intent is een abstract boodschapobject dat kan worden gebruikt om een actie te vragen van een andere app of een verschillende component binnen dezelfde app (“Intents and Intent Filters”, s.d.). Java bytecode Een complexe tussentaal die begrepen wordt door de Java Virtual Machine. Java-syntax wordt door de compiler omgezet naar Java bytecode. Library Het begrip ‘library’ kan vrij vertaald worden als ‘bibliotheek’. Het is een verzameling van samenhangende functies die kunnen worden gebruikt in verschillende projecten. Manifest Een XML-bestand met informatie over besturingssysteem (“App Manifest”, s.d.). Method overloading De mogelijkheid om binnen eenzelfde klasse verschillende methodes met dezelfde naam, maar een andere implementatie te hebben (“Function overloading”, s.d.). Minification Het verkleinen van een applicatie door niet-gebruikte code te verwijderen de applicatie voor het en de overblijvende klassen, velden en methodes compactere namen te geven (“ProGuard”, s.d.). 9 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Null Referentietypes kunnen een null-waarde bevatten. ‘Null’ wijst erop dat de variabele geen concrete referentie bezit naar een object in het geheugen (“Chapter 2. The Structure”, s.d.). NullPointerException Een fout die optreedt wanneer eigenschappen of methodes van een variabele met een null-referentie worden aangeroepen. Obfuscation Het verduisteren van de code door klassen, velden en methodes compacte en onlogische namen te geven (“ProGuard”, s.d.). Objectgeoriënteerd programmeren Een programmeervorm die het imperatief programmeren tracht te structureren. Er wordt daartoe gebruikgemaakt van objecten die de verschillende concepten in de vraagstelling van de applicatie voorstellen (“What is object-oriented programming?”, s.d.). Open source De term ‘open source’ beschrijft software waarvan de broncode vrij toegankelijk is (“Open source”, s.d.). Parsen Het uitlezen van een bepaald bestandsformaat in een programmatorisch meer bruikbaar formaat. Een voorbeeld is het uitlezen van een JSONdocument in objecten en attributen (“What is parsing?”, s.d.). ProGuard Gereedschap binnen Android dat de code minimaliseert en verduistert (“ProGuard”, s.d.). Property De combinatie van een field, een getter en een setter (Leiva, 2015, p. 25). Resource qualifiers Worden gebruikt om, afhankelijk van de karakteristieken van een toestel, andere bronbestanden voor afbeeldingen, tekst en lay-out te leveren aan de applicatie. Een toestel met een hogere schermresolutie vereist bijvoorbeeld grotere afbeeldingen (“Providing Alternative Resources”, s.d.). Root type Het basistype in een programmeertaal, waar ieder ander type, met uitzondering van de primitieve datatypes, van overerft (“Any”, s.d.). Runtime Het begrip ‘runtime’ is een synoniem voor de fase waarin een applicatie wordt uitgevoerd. Scope Het gedeelte van een applicatie waarin een bepaalde variabele of functie zichtbaar is en dus kan worden benaderd. Setters Laten toe om de waarde van een privaat field van buitenaf aan te passen. Singleton Een klasse waarvan slechts één instantie kan en mag bestaan. 10 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? UI thread Ook wel de ‘main thread’ genoemd. Deze thread wordt aangemaakt door het besturingssysteem bij het opstarten van de applicatie. Hij is verantwoordelijk voor de interactie met de gebruiker en het updaten van de userinterface (“Processes and Threads”, s.d.). View Een element in de lay-out van een applicatie. Wrapperklasse Omhult de waarde van een primitieve variabele in een object dat behandeld wordt zoals een referentietype (“The Numbers Classes”, s.d.). .kt De extensie van Kotlin-bestanden. .class De extensie van bestanden met gecompileerde Java bytecode. 11 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Inhoudsopgave 1.Inleiding 16 2. 18 3. Huidige stand van zaken 2.1. Voortbouwen op de Java 6-puinhoop 19 2.2. Algemene complexiteit van de Android API 20 2.3. Beterschap op komst? 20 2.3.1.Bibliotheken 21 2.3.2. 22 Alternatieve talen Kotlin, een nieuwe hoop? 3.1. Wat is Kotlin? 24 3.2. Hoe werkt Kotlin? 24 3.3. De pijlers van Kotlin 25 3.3.1.Veiligheid 25 3.3.1.1. Kotlin en Java 6 25 3.3.1.2. Java 8 26 3.3.2.Beknoptheid 4. 23 26 3.3.2.1.Kotlin 26 3.3.2.2.Java 27 3.3.3.Interoperabiliteit 27 3.3.4. 28 Open source De mogelijkheden van Kotlin 4.1.Algemeen 29 30 4.1.1.Variabelen 30 4.1.1.1.Notatie 30 4.1.1.2. Type inference 30 4.1.1.3. Smart casts 31 12 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 4.1.1.4. Mutable versus immutable 4.1.2.Functies 31 32 4.1.2.1.Notatie 32 4.1.2.2. Type inference 33 4.1.2.3. Standaardwaarden voor parameters 33 4.1.2.4. Benoemde argumenten 33 4.1.2.5. Top-level functies 34 4.1.2.6. Uitbreidingsfuncties (extension functions) 35 4.1.2.7. Lokale functies 36 4.1.3.Properties 37 4.1.4.Klassen 37 4.1.4.1. Primaire constructor 37 4.1.4.2. Secundaire constructors 38 4.1.4.3. Private constructors 39 4.1.4.4.Dataklassen 4.1.5.Interfaces 39 40 4.1.5.1. Standaardimplementatie van methodes 40 4.1.5.2. Standaardimplementatie van properties 41 4.1.6.Exceptions 4.1.6.1. Try catch finally 4.1.7.Datatypes 41 41 42 4.1.7.1. Primitieve datatypes versus referentietypes 42 4.1.7.2. Any en Any? 42 4.1.7.3.Unit 43 4.1.8.Lambda-expressies 43 4.1.8.1. Wat zijn lambda-expressies? 43 13 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 4.1.8.2.Notatie 43 4.1.8.3. Ter vervanging van anonieme klassen 43 4.1.8.4. Member references 44 4.1.9. Visibility modifiers 45 4.1.10. Statische methodes en properties 46 4.1.11.Singletons 4.2. Voor Android 4.2.1. 47 Kotlin Android Extensions 47 4.2.2.Java-naar-Kotlin-converter 48 4.2.3.Anko 48 4.2.3.1.Lay-outs 48 4.2.3.2. 51 Lay-outs: de achtergrond 4.2.3.3.Intents 52 4.2.3.4. 53 Argumenten voor Fragments 4.2.3.5.Services 53 4.2.3.6. Qualifiers 53 4.2.3.7. Toasts en Dialogs 54 4.2.3.8. Asynchrone taken 55 4.2.3.9.SQLite 5. 46 De voordelen van Kotlin voor Android-ontwikkelaars 56 59 5.1. Perfecte integratie met IDE 60 5.2. Lage leercurve 60 5.3. Lichtgewicht programmeertaal met weinig runtimekosten 60 5.4. Null-veiligheid reduceert fouten 61 5.5. Kotlin verhoogt productiviteit 61 5.6. Ondersteuning voor Java 6 61 14 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 6. 7. 5.7. Ondersteuning vanuit JetBrains en gegarandeerde toekomst 62 5.8.Interoperabiliteit 62 De nadelen van Kotlin voor Android-ontwikkelaars 63 6.1. Nieuwe taal, nieuwe termen 64 6.2. Null-veiligheid valt weg door interoperabiliteit 64 6.3. Benoemde argumenten maken deel uit van API 64 6.4. De taal is nog niet volwassen 64 6.5. Wachten op Java 8 65 6.6. Kleine community 65 6.7. Link met IDE’s van JetBrains 66 6.8. Extra kosten 66 6.9. Tegendraadsheid Kotlin 66 Toekomst van Kotlin 8.Praktijkvoorbeeld 67 69 8.1.Buildtijden 70 8.2. Het aantal lijnen code 71 8.3. De grootte van het APK-bestand 72 8.4. Het aantal methodes 73 9.Conclusie 74 15 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 1.Inleiding 16 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? De laatste jaren veranderde er heel wat in de wereld van de informatietechnologie. Tablets en smartphones werpen zich steeds meer op als primaire digitale informatiebronnen, ten nadele van de traditionele computersystemen. Volgens Google (Dischler, 2015) overschreed het mobiele gebruik van de zoekmachine in mei 2015 in tien landen zelfs reeds dat van desktops en laptops. In die mobiele context heeft Android zich in een sneltempo opgewerkt tot een succesvol platform dat bijgevolg niet kan worden genegeerd bij de ontwikkeling van mobiele toepassingen. Toch rolt Google, het bedrijf dat instaat voor de ontwikkeling van Android, geen rode loper uit voor de developers. Het besturingssysteem dat het vandaag aanbiedt, is immers gebaseerd op een framework dat de test met de meest moderne programmeertalen niet langer doorstaat. Bovendien creëert het in zijn poging om de developer zo veel mogelijk vrijheid te geven, extra complexiteit die het ontwikkelen bemoeilijkt (Wharton, 2015a). In de loop der jaren werden vele potentiële oplossingen gelanceerd die die problematiek met wisselend succes trachtten op te lossen. Ook Kotlin, een alternatieve Java-taal die ontwikkeld werd door JetBrains, probeert het schrijven van Android-applicaties te vereenvoudigen. Het recent verlaten betastadium en de specifiek op dat platform gerichte gereedschappen, maken deze taal een interessant onderwerp voor nader onderzoek. Deze bachelorproef gaat dan ook dieper in op het hoe, wat en waarom van Kotlin en tracht op basis van een reeks argumenten de zin of onzin van de programmeertaal voor Android-ontwikkelaars aan te tonen. Om een volledig beeld van het Android-landschap te schetsen, worden eerst en vooral de beperkingen van het standaardplatform besproken. Daarbij worden ook reeds een aantal andere oplossingen en alternatieven onder de loep genomen. De daaropvolgende onderdelen richten zich op de filosofie die aan de basis ligt van Kotlin en de mogelijkheden die het platform aan Java- en Android-ontwikkelaars te bieden heeft. Na die uitgebreide kennismaking worden zowel de sterktes als de zwaktes verder belicht vanuit het standpunt van de developer. Ten slotte wordt de proef op de som genomen in een voorbeeldapplicatie, waarin de daadwerkelijke meerwaarde, syntaxefficiëntie en performantie van Kotlin kunnen worden gemeten. Deze bachelorproef is geschreven volgens de methode ‘uitgebreide literatuurstudie’ en richt zich tot een publiek dat reeds heeft kennisgemaakt met de basisconcepten van het objectgeoriënteerd programmeren, de Java-taal en het Android-framework. 17 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 2.Huidige stand van zaken 18 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 2.1. Voortbouwen op de Java 6-puinhoop Google Android en de Java-programmeertaal hebben samen een lange traditie. Al vanaf de eerste versies van het besturingssysteem werden Java-bibliotheken voorzien als basis voor de ontwikkeling van toepassingen. De libraries die Google hier gebruikt, mogen we overigens niet verwarren met die van Sun en later Oracle, de eigenlijke ontwikkelaars van Java (Clarke, 2016). Google en Oracle zijn er immers nooit in geslaagd een akkoord te bereiken over een licentie voor het gebruik van de basisbibliotheken van Java. Die problematiek noopte de zoekgigant ertoe zich te richten tot een open source-implementatie van de programmeertaal, namelijk Apache Harmony. Intussen is het eerdergenoemde Harmony-project al vijf jaar stopgezet wegens een gebrek aan ondersteuning en de komst van betere alternatieven zoals OpenJDK, een open sourcevariant van Oracle zelf. Niettemin blijft Google vasthouden aan een, weliswaar sterk aangepaste, versie ervan (Amadeo, 2016). Net dat zorgt ervoor dat Android de meest recente Java-updates niet kan volgen en nu gebruikmaakt van een variant die het midden houdt tussen Java 6 en Java 7, in plaats van het huidige Java 8. Michael Pardo schetste deze situatie reeds als de Java 6-puinhoop, een woestenij van twee verouderde Java-versies die de ontwikkelaar belet om gebruik te maken van de nieuwe mogelijkheden en syntactische voordelen die moderne programmeertalen, waaronder ook Java 8, te bieden hebben (2015). In een uiteenzetting op de Øredev-conferentie in 2015 gaf Jake Wharton een overzicht van de belangrijkste Java 8-toevoegingen die tot op heden ontbreken in Android (2015a): • Het java.time-package introduceerde een nieuwe manier van omgaan met tijdstippen en data, waarbij heel wat complexiteit die verbonden was aan de oude Calendar- en Date-API’s werd opgeheven. • Java 8 betekende eveneens de introductie van streams in de programmeertaal. Streams stellen een sequentie van waarden voor, die een voor een door een ketting van operaties kunnen worden bewerkt of verwerkt. Ze verschillen van Collection-types door de afwezigheid van functionaliteit om waarden blijvend bij te houden (Goetz, 2014). • Lambda’s laten toe om functies als waarden te behandelen, waardoor ze voor uitvoer meegegeven kunnen worden aan andere functies (Jemerov & Isakova, 2015, p. 92). • Method references maken het mogelijk om een verwijzing te maken naar een methode of constructor, zonder die meteen uit te voeren (Jemerov & Isakova, 2015, p. 102). • Anonieme klassen zonder referentie naar de klasse waarin ze genest zijn, maken het mogelijk dat er slechts een instantie van die klasse wordt aangemaakt. Wanneer de anonieme klasse wel referenties bezit naar de klasse waarin hij is genest, dan moet telkens wanneer de code wordt uitgevoerd, een nieuwe instantie van die anonieme klasse aangemaakt worden (Wharton, 2015b, p. 14). 19 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Tot slot noemt Wharton ook de algemene breedsprakigheid, een overdaad aan code voor kleine operaties, een probleem dat niet enkel Java 6 maar ook nog steeds Java 8 treft (2015a). 2.2. Algemene complexiteit van de Android API Dat laatste argument geldt ook voor de Android API die Google gebouwd heeft bovenop Apache Harmony. De ontwerpers van het framework hadden vanaf het begin een zo efficiënt mogelijk besturingssysteem in gedachten, wat ze wilden combineren met een grote vrijheid voor de applicatieontwikkelaars. Beide zaken brengen evenwel met zich mee dat het creëren van complexe Android-applicaties heel wat pijnlijke boilerplate code of herhaalde standaardcode vereist (Wharton, 2015a). 2.3. Beterschap op komst? Google heeft reeds signalen uitgezonden die wijzen op beterschap. Zo gaf de technologiereus aan het einde van 2015 aan dat de volgende versie van Android (codenaam Android N) de Harmonyimplementatie van Java vaarwelzegt, ten voordele van het open source OpenJDK-project van Oracle. Deze library wordt wel actief geüpdatet en gaat aldus mee met de officiële Java-versies van Oracle (Protalinski, 2015). OpenJDK ondersteunt functionaliteit zoals de eerdergenoemde lambda’s en streams, wat erop wijst dat ze eveneens hun weg zullen vinden naar de volgende versies van Android. Niettemin zullen de meeste ontwikkelaars nog niet meteen gebruik kunnen maken van al die nieuwe mogelijkheden, aangezien de oude versies Harmony zullen blijven gebruiken (Wharton, 2015b, p 19). Volgens gegevens van maart 2016 heeft het in 2014 gelanceerde Android Lollipop momenteel nog steeds het grootste percentage gebruikers, namelijk 36,1%. Het wordt daarin op de voet gevolgd door het uit 2013 daterende Android KitKat, dat 34,3% van de gebruikersbasis achter zich heeft. Het in oktober vrijgegeven Android Marshmellow moet het stellen met slechts 2,3% (“Platform versions”, 2016). Die cijfers in acht genomen, zal het nog steeds een drietal jaar duren alvorens een voldoende groot aantal gebruikers is overgestapt op een versie met volledige ondersteuning voor Java 8. Marshmallow - 2,3% Lollipop - 36,1% KitKat - 34,3% Jelly Bean - 22,3% Ice Cream Sandwish - 2,3% Gingerbread - 2,6% Froyo - 0,1% Figuur 1: Verdeling van de Android-versies in maart 2016 (“Platform versions”, 2016). Midden maart 2016 gaf David Burke, de Vice President of Engineering van Google, al enkele details vrij over de toekomstige N-versie van Android. Daaruit blijkt dat het besturingssysteem wel degelijk 20 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Java 8-ondersteuning zal krijgen. Een aantal functies, zoals lambda’s, zullen zelfs achterwaarts compatibel zijn tot en met Android Gingerbread (2.3). De meeste Java 8-nieuwigheden blijven evenwel voorbehouden voor de nieuwste versie (Burke, 2016). Bijgevolg zal het nog steeds een aantal jaren vragen alvorens ze volledig ingeburgerd zijn. Intussen reiken creatieve ontwikkelaars tal van oplossingen aan die de eerder beschreven problemen met Java in het algemeen en Android in het bijzonder nu reeds trachten op te lossen. Ze kunnen onderverdeeld worden in twee categorieën: bibliotheken en alternatieve talen. 2.3.1.Bibliotheken Bibliotheken bieden typisch een oplossing voor een individueel programmatorisch vraagstuk. Zo zijn er verschillende die de hiaten in de huidige Java-versies van Android aanschrijven: ThreeTen Android Backport (https://github.com/JakeWharton/ThreeTenABP) maakt het java.time-package beschikbaar, terwijl RxJava (http://reactivex.io/) streams voorziet en Retrolambda (https://github.com/orfjackal/ retrolambda) lambda-expressies en method references naar Android brengt (Wharton, 2015a). Deze libraries mogen er dan wel in slagen heel wat Java 8-features naar Android te brengen, toch kampen ze met een belangrijk nadeel. Elk van hen impliceert immers een reeks extra methodes, wat zorgt voor een groter APK-bestand (de ruimte die de app inneemt, wordt groter) en een naderende DEX-limiet. Android compileert de code van een applicatie namelijk naar een Dalvik Executable (DEX) met bytecode-instructies die de Dalvik Virtual Machine (tot Android 4.4) of de Android Runtime (vanaf Android 5.0) kunnen uitvoeren (“Glossary”, s.d.). Dit DEX-bestand kan maximaal 65.563 methodes bevatten. Wordt die limiet overschreden, dan moet het bestand via MultiDexing gesplitst worden in een primaire DEX-file en een of meerdere secundaire files. Het gebruik van MultiDexing heeft evenwel beperkingen voor Android-versies die nog gebruikmaken van de Dalvik Virtual Machine: zowel de compilatie als de opstart van de applicatie kunnen flink meer tijd vragen. De nieuwe Android Runtime (sinds Android 5.0) lost dit probleem grotendeels op, maar heeft, zoals reeds eerder werd aangegeven, momenteel nog een te kleine gebruikersbasis om reeds door alle ontwikkelaars omarmd te worden (Lentzitzky, 2015). Een eigen test met het Dex Method Counts-script van Mihai Parparita (2015) leert dat een eenvoudige applicatie met enkel de eerdergenoemde drie bibliotheken en zonder ProGuard-optimalisatie reeds 23.691 methodes telt. Onderstaande tabel geeft een overzicht van de onderlinge verdeling. API Aantal methodes Android (min SDK 19) 15265 ThreeTenABP (1.0.3) 4 ThreeTenBP (1.3.1) 2827 RxJava (1.1.0) 4828 21 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? API Aantal methodes Java 745 Sun 22 Org.xmlpull.v1 12 Retrolambda Geen informatie, Gradle-plug-in Totaal 23.691 Figuur 2: Methodeverdeling tussen een reeks veelgebruikte Android-bibliotheken. Rekening houdend met die data, spreekt het voor zich dat grote applicaties met veel libraries en eigen methodes vrij snel tegen de DEX-limiet aankijken. Over het algemeen wordt dan ook aangeraden om omzichtig om te springen met het aantal gebruikte bibliotheken en codeoptimaliserende hulpmiddelen zoals ProGuard te implementeren (Käppler, 2015). Bijkomend veranderen deze bibliotheken weinig of niets aan de algemene breedsprakigheid van Java. Het probleem waarbij kleine operaties veel boilerplate code vragen, blijft hier dus bestaan. 2.3.2.Alternatieve talen Java heeft als belangrijk voordeel ten opzichte van andere programmeerplatforms dat de naar Java bytecode gecompileerde syntax wordt uitgevoerd in een zogenaamde Java Virtual Machine (JVM). Daardoor is elke taal die gecompileerd kan worden naar geldige Java bytecode, geschikt voor het creëren van Java-applicaties en dus ook voor Android-applicaties (Leiva, 2015, p. 4). Doorgaans lossen dergelijke talen meerdere programmatorische vraagstukken op in een keer, en trachten ze tegelijkertijd een vereenvoudigde syntax te voorzien. Door de jaren heen zagen verschillende van die alternatieve talen het levenslicht. Scala en Groovy waren bij de eersten, later kwamen daar Clojure, XTend en Ceylon bij. Nog recenter werd ook Kotlin geïntroduceerd als een taal die compileert naar Java bytecode. Kotlin voorziet naast een alternatieve syntax en uitgebreidere functionaliteit ook bijkomende extensies die zich specifiek richten op de ontwikkeling van Android-applicaties. Net omwille van dat gegeven verdienen Kotlin en zijn bijdrage aan Googles besturingssysteem een extra onderzoek. 22 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 3.Kotlin, een nieuwe hoop? 23 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 3.1. Wat is Kotlin? Kotlin werd ontwikkeld door JetBrains, een in Praag gevestigd bedrijf dat bekend geworden is door zijn IDE’s voor onder andere Java, Ruby, PHP, Python, .NET en het web. Ook Android Studio, de officiële ontwikkelingsomgeving die aangeboden wordt door Google, is gebaseerd op de technologie van het bedrijf. De fundamenten van de programmeertaal werden gelegd in 2010 als een antwoord op de Javahindernissen die het bedrijf in zijn eigen ontwikkelingsprocessen tegenkwam (Krill, 2011). Kotlin is dus geen academische taal, ze werd ontwikkeld vanuit de industrie, met als belangrijkste doel een aantal beperkingen van de Java-standaardtaal op te heffen. Op de officiële website wordt Kotlin omschreven als een “statically typed programming language for the JVM, Android and the browser” (“Kotlin programming language”, s.d.). Met statically typed bedoelen de makers dat het datatype van elke expressie in een programma gekend is wanneer het wordt gecompileerd. Op die manier kan de compiler nagaan of de methodes en fields die men tracht aan te spreken, daadwerkelijk bestaan en toegankelijk zijn. Zo probeert men fouten tijdens het uitvoeren van het programma te vermijden. Dynamisch getypeerde talen, zoals Groovy en JRuby, onderscheiden zich daarvan door het weglaten van het datatype bij de declaratie van variabelen en functies. De juiste referenties worden dan aangemaakt tijdens het uitvoeren van het programma, wat inherent een grotere kans op runtime fouten door spellingsmissers in variabelenamen of conflicten in datatypes met zich meebrengt (Jemerov & Isakova, 2015, p. 3). JetBrains noemt de Java Virtual Machine, Android en de browser als mogelijke toepassingsgebieden voor de taal. Android werd expliciet aan die lijst toegevoegd, omdat Kotlin enkele specifieke extensies voorziet die met het oog op dat platform ontwikkeld zijn. Er bestaan ook mogelijkheden om code te compileren tot JavaScript die in de browser kan uitgevoerd worden. Dat laatste project is evenwel op de lange baan geschoven, omdat JetBrains zich eerst en vooral wil concentreren op het stabiel maken van de Java-compilers (Hearn, 2015). 3.2. Hoe werkt Kotlin? Kotlin-code wordt genoteerd in een bestand met .kt-extensie dat net zoals standaard-Java gecompileerd wordt (door een specifieke Kotlin-compiler) naar een .class-bestand. De aldus gegenereerde .classfiles worden vervolgens verpakt als .jar en uitgevoerd door de virtuele machine die aanwezig is op het toestel. Doorgaans is dit de Java Virtual Machine. Voor Android is dit de Dalvik Virtual Machine voor oudere versies van het besturingssysteem (Android 4.4 en ouder) en de Android Runtime voor nieuwe versies (Jemerov & Isakova, 2015, p. 13). Gecompileerde Kotlin-code is afhankelijk van de Kotlin runtime library. Die omvat de standaardbibliotheek van Kotlin en de extensies die de programmeertaal toevoegt aan de Java-basis. Alle applicaties die in Kotlin geschreven worden, hebben deze runtime library nodig om correct te functioneren (Jemerov & Isakova, 2015, p. 13). 24 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Figuur 3: Schematische voorstelling van het buildproces in Kotlin (Jemerov & Isakova, 2016, p. 13). In de meeste gevallen zullen ontwikkelaars zich bij de compilatie van hun programma’s laten bijstaan door build systems zoals Maven, Gradle of Ant. Elk van deze build systems biedt ondersteuning voor Kotlin. Maven en Gradle zullen er bovendien ook voor zorgen dat de Kotlin runtime library automatisch bij de applicatie wordt gevoegd (Jemerov & Isakova, 2015, p. 13). 3.3. De pijlers van Kotlin Kotlin steunt zijn bestaan op een aantal basisprincipes. Die zijn niet uniek. JetBrains heeft niet de bedoeling om nieuwe standaarden te zetten met deze programmeertaal. Integendeel, de pijlers berusten op principes die reeds in andere programmeertalen hun nut hebben bewezen (Jemerov & Isakova, 2015, p. 9). Algemeen kunnen de volgende principes benoemd worden als pijlers van Kotlin: 3.3.1.Veiligheid 3.3.1.1. Kotlin en Java 6 Het crashen van applicaties door fouten met null-waarden wil men over het algemeen graag tot een minimum beperken. Wanneer dit immers voorvalt bij eindgebruikers, kan dit ervoor zorgen dat ze de toepassing niet meer gebruiken. Kotlin tracht dat probleem aan te pakken door situaties waarin nullwaarden kunnen leiden tot fouten, reeds bij het compileren te detecteren. Wanneer de Kotlin-compiler een dergelijke situatie tegenkomt, dan stopt hij het compileren tot de ontwikkelaar de code heeft aangepast en de potentiële NullPointerException heeft opgelost. De standaard-Java-compiler bezit deze functionaliteit niet, waardoor null-fouten kunnen leiden tot crashes (Leiva, 2015, p. 5). Kotlin realiseert die beveiliging tegen null-fouten of NullPointerExceptions door de ontwikkelaar specifiek te laten aangeven of een variabele een null-referentie kan bevatten of niet. Wanneer dat zo is, dan zal bij het compileren een fout getoond worden telkens wanneer de variabele wordt gebruikt zonder te controleren of hij een null-referentie bevat. Variabelen waarvan niet wordt aangegeven dat ze een nullwaarde kunnen bevatten, hoeft men niet te controleren alvorens men ze gebruikt. Een vraagteken ‘?’ bij 25 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? het declareren van de variabele geeft aan of die variabele al dan niet een null-referentie kan bevatten (Leiva, 2015, p. 89). Het volgende voorbeeld illustreert de null-veiligheid van Kotlin: val person1:String = “Kristof” val person2:String? = “Rodric” person1.length person2.length //Compileert //Compileert niet Het eerste statement compileert omdat er garanties zijn dat de variabele person1 geen null-referentie kan bevatten. De tweede expressie compileert dan weer niet omdat de variabele person2 nullable is en dus null kan bevatten. Wil men deze code uitvoeren, dan moet er een controle toegevoegd worden, waarin wordt gecontroleerd of person2 null bevat: if(person2 != null) { person2.length //Compileert wel } Wil men dezelfde veiligheid realiseren in een gewone Java-omgeving zonder Kotlin, dan vraagt dit meer logica: String person1 = “Kristof”; String person2 = “Rodric”; if(person1 != null && person2 != null) { person1.length(); person2.length(); } 3.3.1.2. Java 8 In Java 8 werd naar een oplossing gezocht voor het eerder beschreven NullPointerException-probleem. Er werd een nieuwe klasse Optional<T> toegevoegd, die een waarde van een gespecifieerd type kan bevatten of juist niet kan bevatten (Urma, 2014). Op die manier wordt vermeden dat er in code nog null-referenties worden aangemaakt. Zolang Android geen volledige ondersteuning biedt voor Java 8, is deze klasse evenwel niet bruikbaar voor applicaties in Googles besturingssysteem. 3.3.2.Beknoptheid 3.3.2.1. Kotlin Jemerov en Isakova (2015, p. 10) beschrijven een taal als beknopt wanneer de syntax expressief of zelfverklarend is en weinig wordt verduisterd door boilerplate code. Beknopte code is makkelijk te begrijpen en maakt ontwikkelaars daardoor productiever. De makers van Kotlin hebben heel wat 26 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? werk gestoken in het expressief maken van de structuren die in de Java- en Android-API typisch veel boilerplate code met zich meebrengen. Een voorbeeld van de beknoptheid van Kotlin vinden we in het aanmaken van klassen. Een eenvoudige klasse ‘Student’ met twee velden vergt in Kotlin slechts een lijn code. Met die klassedeclaratie wordt automatisch een constructor aangemaakt en worden ook de getters en setters voor beide velden vanzelf gecreëerd. class Student(val email:String, val name:String) 3.3.2.2. Java Eenzelfde klasse aanmaken in Java vergt heel wat meer code. Zo moet de ontwikkelaar zelf constructors voorzien en getters en setters aanmaken voor velden. Beide zaken zorgen ervoor dat het geheel een stuk minder leesbaar is dan de Kotlin-implementatie van dezelfde klasse. private String email; private String name; public Student(String email, String name) { this.email = email; this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } 3.3.3.Interoperabiliteit Met interoperabiliteit in een programmeeromgeving wordt bedoeld dat twee verschillende, autonome talen in staat zijn om met elkaar te communiceren en te interageren (“Interoperabiliteit”, s.d.). Een van de belangrijkste doelstellingen die de ontwerpers van Kotlin voor zichzelf stelden, was dat de programmeertaal naadloos moest kunnen communiceren met standaard-Java (“Calling Java code from Kotlin”, s.d.). Objecten die afkomstig zijn vanuit Java hebben dus geen conversie nodig om gebruikt 27 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? te worden in Kotlin en omgekeerd. Bovendien kunnen applicatieontwikkelaars alle Java-gebaseerde bibliotheken van derden ook aanschrijven in Kotlin (Jemerov & Isakova, 2015, p. 12). Om de overhead van de taal tot een minimum te beperken, maken de ingenieurs van JetBrains ook zelf zo veel mogelijk gebruik van de standaardbibliotheken die voorzien zijn in Java. Zo heeft Kotlin bijvoorbeeld geen eigen library voor Collection-types. Het gebruikt de functionaliteit die wordt aangeboden door Java en breidt deze uit met nieuwe mogelijkheden (Jemerov & Isakova, 2015, p. 12). 3.3.4.Open source Hoewel Kotlin ontwikkeld wordt door een commerciële organisatie, is de taal volledig open source. Dat wil zeggen dat iedereen de API en de compiler gratis kan gebruiken en er ook zelf bijdrages toe kan leveren (Jemerov & Isakova, 2015, p. 6). 28 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 4.De mogelijkheden van Kotlin 29 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Kotlin voegt een aantal specifieke mogelijkheden toe bovenop de functionaliteit die reeds aangeboden wordt door Java. Bovendien heeft de programmeertaal een licht andere syntax. In hetgeen wat volgt, worden de kenmerken en mogelijkheden van Kotlin besproken die het meest significant zijn voor Android-ontwikkelaars. Daarbij wordt versie 6 van Java als basis genomen, aangezien Android op dit moment nog geen volledige ondersteuning biedt voor de nieuwste variant (8). Tot slot worden ook nog de specifieke Android-bibliotheken van Kotlin bestudeerd. 4.1. Algemeen 4.1.1.Variabelen Kotlin hanteert andere regels dan Java bij het omgaan met variabelen. De belangrijkste concepten zijn hier type inference, smart casts en mutability. 4.1.1.1. Notatie De declaratie van variabelen start met een statement dat de veranderlijkheid aangeeft (var of val) en wordt gevolgd door de naam van die variabele. Na een dubbelepunt kan een eventueel datatype aangegeven worden. Naam Datatype Optionele null-aanduiding val variabele:String? = “Variabele” Aanduiding onveranderlijk (val) of veranderlijk (var) Waarde Figuur 4: Notatie van een variabele in Kotlin. 4.1.1.2. Type inference De Kotlin-compiler kan in de meeste gevallen het type van een variabele afleiden uit de context. In dat geval moet het datatype niet expliciet aangegeven worden (Jemerov & Isakova, 2015, p. 3). Dat verklaart ook meteen Kotlins keuze om te werken met val- en var-statements bij de declaratie van variabelen. Type inference zorgt ervoor dat de code een stuk beknopter en leesbaarder wordt. val value1 = 13 val value1Class = value1.javaClass //int val value2 = “Value” val value2Class = value2.javaClass //String Wanneer wordt gewerkt met variabelen die een null-referentie kunnen bevatten, dan moet het datatype wel expliciet aangegeven worden. Het type kan immers niet afgeleid worden uit een null-waarde. Hetzelfde geldt voor situaties waarin men een waarde wenst bij te houden als een meer generisch type. Zo erft de klasse Activity in het bijgevoegde voorbeeld over van de klasse Context. Wanneer een instantie van Activity met type inference zou worden opgeslagen in een variabele, dan heeft die 30 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? variabele Activity als datatype. Indien het overkoepelende datatype Context gewenst is, dan moet dit expliciet aangegeven worden bij de declaratie (Leiva, 2015, p. 25). val value3: String? = null val value4: Context = getActvitiy() //Type Context val value5 = getActivity() //Type Activity 4.1.1.3. Smart casts Wanneer het datatype van een variabele gecontroleerd wordt en wanneer deze check slaagt, dan zal de compiler voor die variabele automatisch een smart cast uitvoeren. Dat wil zeggen dat die variabele niet meer expliciet moet gecast worden. De casting is immers reeds uitgevoerd door de compiler (“Type Checks and Casts”, s.d.). In het onderstaande voorbeeld wordt de variabele value1 automatisch gecast naar een String na de if-controle. val value1:Any = “Kotlin” //Any is root type if(value1 is String) { val length = value1.length } } 4.1.1.4. Mutable versus immutable Variabelen zijn immutable of onveranderlijk wanneer hun waarde na initialisatie niet meer kan worden gewijzigd. Ze worden gedeclareerd met behulp van het val-statement. Mutable of veranderlijke variabelen kunnen daarentegen wel nog gewijzigd worden na hun initialisatie. Het var-statement wijst op een veranderlijke variabele (Leiva, 2015, p. 25). val person1 = “Rodric” person1 = “Kristof” //Compileert niet var person2 = “Rodric” person2 = “Kristof” //Compileert wel Het concept van onveranderlijke variabelen is bijzonder populair binnen het functioneel programmeren en wordt ook door Kotlin luid aangemoedigd. Het gebruik ervan zorgt er namelijk voor dat ongewenste neveneffecten bij het oproepen van functies kunnen worden vermeden. Neveneffecten komen voor wanneer de interne werking van een functie de waarde van een variabele wijzigt buiten het medeweten van diegene die de functie aanroept (Jenkins, 2015). Dit gedrag kan leiden tot het crashen van de applicatie en tot lange zoektochten naar de oorzaak van de wijziging in de waarde. In Android-applicaties die gebouwd zijn met standaard-Java, worden veranderlijke variabelen doorgaans het meest gebruikt. Enkel wanneer ze als final worden gedeclareerd, is er sprake van onveranderlijkheid. Kotlin heeft een duidelijke voorkeur voor die laatste soort variabelen. De taal voorziet wel in een copy-methode waarmee volledige objecten kunnen worden gekopieerd. Bij die operatie kunnen ook 31 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? wijzigingen aangebracht worden in de velden (“Data Classes”, s.d.). Het onderstaande voorbeeld maakt gebruik van een klasse ‘Student’ met twee velden. Er wordt een eerste instantie gemaakt, die vervolgens wordt gekopieerd met behulp van de automatisch geïmplementeerde copy-methode. Bij die laatste operatie wordt ook de naam van de student gewijzigd. //Klasse student data class Student(val name:String, val email:String) val student1 = Student(“Jack”, “[email protected]”) //Naam: Jack, email: jack@... val student2 = student1.copy(name = “Jill”) //Naam: Jill, email: jack@... 4.1.2.Functies Ook functies zien er niet helemaal hetzelfde uit als in Java. Bovendien beschikken ze in Kotlin over heel wat meer mogelijkheden. 4.1.2.1. Notatie De declaratie van een functie start in Kotlin met het fun-statement en wordt gevolgd door een functienaam. Daarop volgt de lijst met parameters. Een eventueel returntype kan aangegeven worden achter de parameterdeclaratie (Jemerov & Isakova, 2015, p. 19). Naam Parameters Body fun functie(parameter:String):String { ... } Aanduiding functie Returntype Figuur 5: Notatie van een functie in Kotlin (Jemerov & Isakova, 2015, p. 18). fun add(a:Int, b:Int):Int { return a + b } Functies met een returntype en een body die bestaat uit één expressie, kunnen een flink stuk vereenvoudigd worden. Het is dan niet langer nodig om de expressie tussen accolades te noteren, men kan ze gewoon achter de functiedeclaratie plaatsen. Dergelijke functies worden ook wel singleexpression functions genoemd (“Functions”, s.d.). Het volgende voorbeeld toont een vereenvoudigde versie van de vorige code. fun add(a:Int, b:Int):Int = a + b Wanneer een functie geen returnwaarde heeft, dan wordt het returntype in Java gespecifieerd als void. Kotlin heeft een gelijkaardig datatype, namelijk Unit. 32 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 4.1.2.2. Type inference Bij single-expression functions kan het returntype desgewenst weggelaten worden. De Kotlin-compiler kan hier namelijk net zoals bij variabelen het datatype van de teruggegeven waarde afleiden uit de context. De eerdergetoonde add-functie kan dus nog verder gereduceerd worden (“Functions”, s.d.). fun add(a:Int, b:Int) = a + b 4.1.2.3. Standaardwaarden voor parameters Kotlin voorziet mogelijkheden om standaardwaarden toe te kennen aan parameters van een functie. Die techniek maakt het werken met optionele parameters mogelijk. Enkel zij die geen standaardwaarde hebben gekregen, moeten verplicht ingevuld worden. (Jemerov & Isakova, 2015, p. 48). val value1 = add(5) //6 val value2 = add(5, 3) //8 fun add(a:Int, b:Int = 1) = a + b Waar men in standaard-Java method overloading nodig heeft om de illusie van optionele parameters te wekken, volstaat in Kotlin een enkele methode met ingevulde standaardwaarden. Aangezien Java dit concept niet kent, moeten voor alle parameters waarden worden voorzien wanneer een dergelijke Kotlin-functie vandaaruit wordt aangeroepen. JetBrains levert hier evenwel een oplossing voor via de @ JvmOverloads-annotatie, die automatisch de overeenkomstige method overloads voor Java genereert (Jemerov & Isakova, 2015, p. 48). //In Kotlin @JvmOverloads fun add(a:Int, b:Int = 1) = a + b //In Java public int add(int a, int b) { return a + b; } public int add(int a) { return a + 1; } 4.1.2.4. Benoemde argumenten Bij het oproepen van functies in Kotlin kunnen argumenten meegegeven worden via de naam van hun overeenkomstige parameter. Die techniek vereenvoudigt het aanroepen van functies met veel of optionele parameters. Bovendien speelt ook de volgorde waarin de argumenten worden doorgegeven dan niet langer een rol (“Functions”, s.d.). Bijgevoegd voorbeeld ondersteunt die laatste stelling. fun add(a:Int, b:Int = 1) = a + b val value = add(b = 5, a = 5) 33 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? De Java- en Android-API’s bieden geen ondersteuning voor dit concept. Bijgevolg kunnen methodes die daarin gedefinieerd zijn, niet aangeroepen worden met benoemde argumenten. Enkel functies die in Kotlin opgesteld zijn, kunnen via deze techniek tot uitvoer gebracht worden (Jemerov & Isakova, 2015, p. 15). 4.1.2.5. Top-level functies In de meeste programmeertalen moeten functies en properties deel uitmaken van een klasse. In grote projecten brengt deze regel evenwel vaak extra complexiteit met zich mee, omdat er steeds functies zijn die niet meteen ondergebracht kunnen worden in een bestaande klasse. Oplossingen die dan ook vaak gebruikt worden, zijn het aanmaken van een specifieke klasse voor die ene functie of het creëren van een neutrale klasse met een hele reeks statische methodes. Kotlin biedt een oplossing voor deze problematiek door toe te laten dat functies (en ook properties) buiten een klasse worden gedefinieerd. Deze zogenaamde top-level functies maken wel nog steeds deel uit van het package dat gespecifieerd wordt in het bestand waarin ze ondergebracht zijn. Dat betekent dat het package moet geïmporteerd worden in klassen die deze functies aanroepen (Jemerov & Isakova, 2015, p. 48). Het voorbeeld toont een bestand CalculatorUtil waarin add is gedefinieerd als een top-level functie. Add wordt vervolgens geïmporteerd in MainActivity en aangeroepen in diens onCreate-methode. CalculatorUtil.kt package com.kristofcolpaert.example10functiontoplevelfunction.util fun add(a:Int, b:Int = 1) = a + b MainActivity.kt package com.kristofcolpaert.example10functiontoplevelfunction import android.support.v7.app.AppCompatActivity import android.os.Bundle import com.kristofcolpaert.example10functiontoplevelfunction.util.add class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val value = add(5, 5) } } De Java Virtual Machine, Dalvik Virtual Machine en Android Runtime zijn niet in staat om functies en properties te herkennen buiten een klasse. Daarom zal de Kotlin-compiler deze top-level functies in de achtergrond toch compileren naar statische methodes in een klasse. Die klasse neemt dan de naam 34 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? over van het bestand plus zijn extensie. In het voorgaande voorbeeld wordt dat dan CalculatorUtilKt. In standaard-Java worden Kotlins top-level functies eveneens aangeroepen als statische methodes van deze door de compiler gegenereerde klassen (Jemerov & Isakova, 2015, p. 49). Onderstaand voorbeeld illustreert dit. package com.kristofcolpaert.example10functiontoplevelfunction; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import com.kristofcolpaert.example10functiontoplevelfunction.util. CalculatorUtilKt; public class SecondaryActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int value = CalculatorUtilKt.add(5, 5); } } 4.1.2.6. Uitbreidingsfuncties (extension functions) Grote projecten krijgen vaak te maken met een heleboel helperklassen met statische methodes, die functionaliteit toevoegen aan de basis-API’s van Java, Android en andere frameworks. Zo zal bijvoorbeeld een klasse IntegerHelpers een reeks van statische methodes bevatten die het Integerdatatype uitbreiden. Het belangrijkste nadeel van die manier van werken, is dat het object waarop de operatie moet worden uitgevoerd, ook steeds als argument moet worden meegegeven (Leiva, 2015, p. 28). In Kotlin is een mogelijkheid voorzien om nieuwe methodes rechtstreeks op bestaande klassen van Java, Android of externe bibliotheken te declareren. Deze zogenaamde uitbreidingsfuncties (of extension functions) worden niet genoteerd als onderdelen van de beoogde klasse, maar komen erbuiten te staan (“Extensions”, s.d.). Dat maakt dat ze niet automatisch over het volledige project beschikbaar zijn. Het package waartoe ze behoren, moet nog steeds geïmporteerd worden in de klassen waar men ze wenst te gebruiken. Wanneer dat gebeurd is, kunnen de uitbreidingsfuncties via de dotnotatie aangeroepen worden op elke instantie van de klasse die ze uitbreiden (Jemerov & Isakova, 2015, p. 51). Het voorbeeld toont een bestand IntegerUtil waarin een uitbreidingsfunctie add op het datatype Int wordt gedefinieerd. In MainActivity wordt de aangemaakte functie getest op een Int-waarde. 35 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? IntegerUtil.kt package com.kristofcolpaert.example11functionextensionfunction.util fun Int.add(b:Int = 1) { this + b } MainActivity.kt package com.kristofcolpaert.example11functionextensionfunction import android.support.v7.app.AppCompatActivity import android.os.Bundle import com.kristofcolpaert.example11functionextensionfunction.util.add class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val value = 5 value.add(5); //10 } } Kotlin voorziet eveneens compatibiliteit naar Java. Uitbreidingsfuncties zijn immers beschikbaar als statische methode van het bestand waarin ze gedefinieerd zijn (Jemerov & Isakova, 2015, p. 52). In het voorgaande voorbeeld wordt dat dan IntegerUtilKt. Bijgevoegde code toont de aanroep van een uitbreidingsfunctie in Java. int value = 5; IntegerUtilKt.add(value, 5); Belangrijk om te weten is dat de Kotlin-API ook zelf voor een groot deel is opgebouwd uit extension functions die gedefinieerd zijn bovenop de standaardbibliotheken van Java (Jemerov & Isakova, 2015, p. 60). 4.1.2.7. Lokale functies Kotlin ondersteunt ook lokale functies. Dat zijn methodes die zijn ingebed in een andere methode. Ze hebben toegang tot alle variabelen en parameters die zijn gedefinieerd in de scope van de bovenliggende methode en kunnen bovendien ook enkel vandaaruit benaderd worden (“Functions”, s.d.). Lokale functies maken de code overzichtelijker en worden vaak gebruikt om bijvoorbeeld validatie van parameters toe te voegen aan een functie. In het bijgevoegde voorbeeld wordt de reeds gekende 36 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? add-functie uitgebreid zodat ze ook kan worden gebruikt met argumenten van het type Double. De parameters krijgen daarom een meer generisch datatype Any. De validatiefunctie in add controleert of de ingevulde argumenten wel degelijk Int of Double zijn. fun add(a:Any, b:Any):Double { fun validate(c:Any):Boolean { if(c is Int || c is Double){ return true } return false } if(validate(a) && validate(b)) { return a as Double + b as Double } throw IllegalArgumentException(“Arguments should be Int or Double”) } 4.1.3.Properties Fields worden in Kotlin ook wel properties genoemd. Dat komt omdat de taal hen standaard uitbreidt met getters en setters. De applicatieontwikkelaar hoeft die dus niet zelf aan te maken (Leiva, 2015, p. 25). Voor properties gelden min of meer dezelfde mogelijkheden als voor functies. Zo kan men bijvoorbeeld ook top-level properties definiëren alsook extension properties die bestaande klassen uitbreiden. 4.1.4.Klassen Het aanmaken en gebruiken van klassen in Kotlin verschilt aanzienlijk van Java. Zo is bijvoorbeeld het new-statement bij het maken van nieuwe instanties niet langer verplicht. Verder zijn Kotlin-klassen standaard final, wat wil zeggen dat andere klassen er niet van kunnen overerven. Pas wanneer ze gedeclareerd worden met het open-statement als voorvoegsel, kunnen er anderen van overerven. De meeste afwijkingen die Kotlin op klassevlak vertoont ten opzichte van Java, beogen een beknoptere en beter leesbare code. 4.1.4.1. Primaire constructor Een Kotlin-klasse heeft in de meeste gevallen maar een constructor nodig. Die wordt ook wel de primaire constructor genoemd en maakt deel uit van de klassehoofding. Hij kan een verzameling parameters ontvangen, die hij ter initialisatie van het object doorgeeft aan het initialisatieblock in de body van de klasse. Dat initialisatieblock wordt gespecifieerd door het init-statement en is automatisch verbonden aan de primaire constructor. Het wordt dan ook gebruikt om het aangemaakte object een aanvankelijke configuratie te geven (“Classes”, s.d.). De voorbeeldcode toont een klasse ‘Student’ met vier eigenschappen: firstname, lastname, email en course. Alle eigenschappen worden toegekend aan fields (velden) in het initialisatieblock. 37 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? class Student(_firstname:String, _lastname:String, _email:String, _ course:String) { val firstname:String val lastname:String val email:String val course:String init { this.firstname = _firstname this.lastname = _lastname this.email = _email this.course = _course } } In gevallen waarin het initialisatieblock zich beperkt tot het initialiseren van fields op basis van de doorgegeven argumenten, voorziet Kotlin een nog eenvoudigere syntax. De parameters in de eigenlijke constructor kunnen als fields gedeclareerd worden door ze te voorzien van een val- of var-statement. Het initialisatieblock en de declaratie van de fields kunnen in dat geval achterwege gelaten worden (Jemerov & Isakova, 2015, p. 72). Het onderstaande voorbeeld illustreert dit. class Student(val firstname:String, val lastname:String, val email:String, val course:String) Net zoals bij functies is het mogelijk om parameters van een constructor een standaardwaarde mee te geven. Dat principe maakt constructor overloading in principe overbodig. Aangezien Java het concept van parameters met standaardwaarden niet eigen is, genereert de compiler in de achtergrond constructors die overeenkomen met alle beschreven situaties in Kotlin (Jemerov & Isakova, 2015, p. 74). class Student(val firstname:String, val lastname:String, val email:String, val course:String = “NMCT”) Wanneer er geen primaire constructor aanwezig is, zal bij het compileren automatisch een lege standaardconstructor zonder parameters voorzien worden (“Classes”, s.d.). 4.1.4.2. Secundaire constructors Meestal volstaat een primaire constructor, maar in sommige gevallen zijn toch bijkomende constructors gewenst. Deze secundaire constructors worden in de body van de klasse genoteerd en voorafgegaan door het constructor-statement. Elk van hen moet verplicht de primaire constructor aanschrijven wanneer die aanwezig is. Dat gaat via het this-statement, waarna een verzameling argumenten kan worden meegegeven (“Classes”, s.d.). Secundaire constructors mogen in principe niet gebruikt worden om parameters optioneel te maken. Hetzelfde kan immers bereikt worden door te werken met standaardwaarden. Het volgende voorbeeld gaat echter omwille van eenvoud tegen die regel in. 38 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? class Student(val firstname:String, val lastname:String, val email:String, val course:String) { constructor(firstname: String, lastname: String, course: String) :this(firstname, lastname, firstname + “.” + lastname + “@student. howest.be”, course){ } } 4.1.4.3. Private constructors Private constructors voorkomen het instantiëren van een klasse. Dat kan bijvoorbeeld gewenst zijn bij het werken met een singleton of klassen die volledig opgebouwd zijn uit statische methodes en properties. Een primaire constructor kan als privaat gemarkeerd worden door in de klassehoofding een private-statement toe te voegen voor de constructordeclaratie. Die laatste moet wel expliciet, dat wil zeggen met behulp van het constructor-statement, genoteerd worden (Jemerov & Isakova, 2015, p. 77). class Student private constructor(){} 4.1.4.4. Dataklassen Applicaties die hevig steunen op de connectie met een web-API, bezitten vaak een heleboel klassen die geen andere taak hebben dan het semantisch groeperen van data en het voorzien van een aantal primitieve operaties (Wharton, 2015b, p. 4). Hen aanmaken vergt bovendien heel wat boilerplate code, omdat er voor elk field (veld) getters en/of setters moeten worden voorzien om de waarde uit dat field op te vragen of in te stellen. Verder zijn ook de acties in die klassen vaak overal dezelfde: een methode om instanties met elkaar te vergelijken, een functie die het object omzet naar een String… Kotlin-klassen voorzien reeds automatisch getters en setters voor alle fields die gespecifieerd worden in een klasse. Wordt de klassedeclaratie voorafgegaan door een data-statement, dan komen daar ook nog een aantal veelgebruikte basisoperaties bij (Jemerov & Isakova, 2015, p. 80). Die omvatten: • toString(): genereert een Stringrepresentatie van het object, waarin alle fields van dat object zijn opgenomen. • hashCode(): geeft een Intwaarde terug op basis van alle fields in het object. Die methode wordt gebruikt om twee objecten met elkaar te vergelijken. • equals(): vergelijkt twee instanties van de klasse. De returnwaarde is een booleaanse waarde. • copy(): maakt een kopie van de instantie. Tijdens die operatie kunnen er ook wijzigingen aangebracht worden in het (nieuwe) object. data class Student(val firstname:String, val lastname:String, val email:String, val course:String) 39 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? De met getters en setters uitgebreide fields van een Kotlin-dataklasse worden ook wel properties genoemd. Het is mogelijk om elke property van een object te mappen naar een variabele. Dat proces wordt binnen de taal multi-declaration genoemd. Het voorbeeld illustreert dat aan de hand van de hierboven getoonde klasse ‘Student’. val student = Student(“Kristof”, “Colpaert”, “kristof.colpaert@student. howest.be”, “NMCT”) val(firstname, lastname, email, course) = student println(firstname) //Kristof 4.1.5.Interfaces De interfaces in Kotlin vertonen zeer sterke gelijkenissen met die in Java 8. Ze bieden heel wat extra mogelijkheden ten opzichte van de basisfunctionaliteit van interfaces in versie 6 en 7 van Java. Kotlin komt daarmee tegemoet aan de Android-ontwikkelaars, die tot op heden nog gebonden zijn aan die oude versies van Java. 4.1.5.1. Standaardimplementatie van methodes Interfaces zijn typisch opgebouwd uit abstracte declaraties van methodes en fields. Klassen die een interface implementeren, moeten dan verplicht alle methodes die erin gespecifieerd worden, voorzien van een concrete implementatie. Kotlin voorziet daarnaast ook de mogelijkheid om methodes in een interface reeds een standaardimplementatie te geven. Die kan dan overschreven worden door de klassen die de interface implementeren, maar dat is niet noodzakelijk (“Interfaces”, s.d.). Bijgevoegde code toont een interface met een functie die een standaardimplementatie heeft gekregen. interface Clickable { fun click() { println(“Interface has been clicked”) } } Klassen die deze interface implementeren, kunnen ervoor kiezen de methode te overschrijven of de standaardimplementatie te gebruiken. Volgend voorbeeld illustreert dit. In het geval van de klasse ‘Rectangle’ zal bij een click de boodschap “Rectangle has been clicked” verschijnen. In het geval van de klasse ‘Circle’ zal het volgende bericht verschijnen: “Interface has been clicked”. class Rectangle : Clickable { override fun click() { println(“Rectangle has been clicked”) } } class Circle : Clickable 40 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Voor gevallen waarin dergelijke Kotlin-interfaces worden aangeroepen in Java-versies zonder ondersteuning voor methodes met een standaardimplementatie, voorziet de compiler naast een interface ook een bijhorende klasse. De interface bevat dan enkel declaraties, terwijl de klasse ze implementeert als statische methodes (Jemerov & Isakova, 2015, p. 69). 4.1.5.2. Standaardimplementatie van properties Interfaces kunnen zelf geen status bijhouden. Dat wil zeggen dat properties die erin gedeclareerd worden, geen waarde kunnen bevatten en zich dus beperken tot een abstracte definitie. Wel kunnen voor properties in Kotlin-interfaces reeds standaardgetters en -setters gedefinieerd worden (“Interfaces”, s.d.). Het voorbeeld illustreert dat aan de hand van een interface ‘Student’, die het e-mailadres via een standaardgetter laat baseren op de naam en voornaam van de desbetreffende student. Klassen die deze interface implementeren, kunnen de getter evenwel nog overschrijven. interface Student { val firstname:String val lastname:String val email:String get() = firstname + “.” + lastname + “@student.howest.be” } 4.1.6.Exceptions Kotlin gooit het volledige concept van checked exceptions overboord. Checked exceptions zijn een typisch programmeerkenmerk van Java en moeten expliciet afgehandeld worden. De ontwikkelaar kan ze niet negeren. Daartegenover staan unchecked exceptions, waarbij de programmeur wel zelf de keuze heeft of hij ze al dan niet afhandelt (Jemerov & Isakova, 2015, p. 39). Checked exceptions zijn volgens Bruce Eckel (s.d.), een vooraanstaand Java-programmeur, een experiment dat het tot de productiefase heeft gehaald. Hij noemt ze theoretisch een goed idee, maar wijst er ook meteen op dat heel wat extra code vereist is om ze af te handelen of alsnog te negeren. Die extra syntax leidt volgens Eckel dan ook te veel de aandacht af van de essentie: de applicatie. 4.1.6.1. Try catch finally Het uit Java (en andere talen) gekende try-catch-finally-partroon is eveneens aanwezig in Kotlin. Daar is het evenwel een expressie, wat wil zeggen dat het een returnwaarde heeft die kan opgevangen worden in een variabele (Jemerov & Isakova, 2015, p.40). Wanneer het try-block slaagt, dan levert dat de returnwaarde. In andere gevallen voorziet het catch-block de teruggegeven waarde. Het bijhorende voorbeeld illustreert een falende code. De waarde van de variabele value2 zal aldus -1 zijn. val value1 = “Kristof” val value2 = try { value1.toInt() } catch(ex:Exception) { -1 41 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? } finally { println(“Done”) } println(value2) //-1 4.1.7.Datatypes Datatypes in Kotlin zijn niet helemaal dezelfde als in Java. Dit hoofdstuk bespreekt de belangrijkste verschillen in de manier waarop beide programmeertalen ze gebruiken. Verder worden ook enkele Kotlin-specifieke kenmerken behandeld. 4.1.7.1. Primitieve datatypes versus referentietypes In Java wordt een duidelijk onderscheid gemaakt tussen zogenaamde primitieve datatypes (primitive types) en referentietypes (reference types). Het belangrijkste verschil tussen beide zit in de manier waarop ze hun waarden bewaren. Waar die eersten ze rechtstreeks bijhouden, bevatten die laatsten een referentie naar de plaats in het geheugen waar het object (de waarde) wordt bewaard. Dat brengt met zich mee dat in het geval van reference types meerdere variabelen een referentie naar eenzelfde object kunnen bevatten (De Jong, 2012). Java kent acht primitieve datatypes: byte, short, int, long, float, double, char en boolean (“Primitive Data Types”, s.d.). Zij hebben als voordeel ten opzichte van referentietypes dat hun waarden makkelijker opgeslagen en doorgegeven kunnen worden. Anderzijds kan men er geen methodes op aanroepen en kunnen ze niet rechtstreeks gebruikt worden in collecties (Jemerov & Isakova, 2015, p. 145). Java voorziet daarom voor elk primitief datatype een wrapperklasse die de waarde omhult in een object dat behandeld wordt zoals een reference type (“The Numbers Classes”, s.d.). De wrapperklassen die horen bij de eerdergenoemde primitieve datatypes zijn: Byte, Short, Integer, Long, Float, Double, Char en Boolean. Kotlin specifieert, in tegenstelling tot Java, enkel wrapperklassen: Byte, Short, Int, Long, Float, Double, Char en Boolean. Dat wil evenwel niet zeggen dat alle waarden automatisch worden bijgehouden als objecten. Tijdens het uitvoeren van het programma, zal de compiler er immers zelf voor kiezen om de waarden op een zo efficiënt mogelijke manier bij te houden. Zo zal een variabele met het Int-datatype van Kotlin alsnog in de meeste gevallen gecompileerd worden naar een primitief int-type van Java. Enkel wanneer nodig, zal een reference type gebruikt worden om de waarde op te slaan. Kotlin abstraheert met andere woorden het verschil tussen primitieve types en referentietypes voor de ontwikkelaar, en laat de keuze tussen beiden afhangen van de compiler (Jemerov & Isakova, 2015, p. 146). 4.1.7.2. Any en Any? De Any-klasse van Kotlin kan vergeleken worden met de Object-klasse van Java. Het is de root van de volledige hiërarchie en de superklasse waarvan elke type dat geen null is, overerft. Wanneer de bij te houden waarde wel null kan zijn, dan is Any? de superklasse (“Any”, s.d.). 42 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Aangezien Kotlin enkel referentietypes kent en elk van die types automatisch overerft van Any of Any?, wil dat zeggen dat elk type in Kotlin een van beide als superklasse heeft. Dat is een belangrijk verschil met Java, waar de primitieve types geen superklasse hebben en dus niet overerven van Object. Wil men Object toch voor die primitieve types gebruiken, dan is men aangewezen op de wrapperklassen (Jemerov & Isakova, 2015, p. 149). 4.1.7.3. Unit Unit wordt gebruikt als returnwaarde van functies die niets teruggeven en dus enkel een operatie uitvoeren. In die zin kan het type vergeleken worden met void in Java. Het enige verschil tussen beide is dat Unit wel degelijk een waarde heeft, namelijk het Unit-object (“Unit”, s.d.). 4.1.8.Lambda-expressies Lambda’s hebben door de jaren heen hun weg gevonden naar de nieuwste versie van Java. Android moet het nog even zonder hen stellen, al heeft Kotlin een oplossing klaar. 4.1.8.1. Wat zijn lambda-expressies? Lambda-expressies, of kortweg lambda’s, zijn een concept dat afkomstig is uit het functioneel programmeren. Men kan ze het best vergelijken met functies, aangezien ook zij een bepaald gedrag representeren. Het belangrijkste verschil tussen beide schuilt in het feit dat lambda’s als waarden kunnen behandeld worden, waardoor men ze kan gebruiken als argument voor een functie (Jemerov & Isakova, 2015, p. 95). 4.1.8.2. Notatie Een lambda-expressie wordt in Kotlin steeds omgeven door accolades. Daarbinnen scheidt een pijl de lijst met parameters aan de linkerkant van de body aan de rechterkant. Het voorbeeld illustreert een lambda in zijn meest eenvoudige vorm (Jemerov & Isakova, 2015, p. 95). Parameters Body {a:Int, b:Int -> a + b} Figuur 6: Notatie van een lambda-expressie in Kotlin (Jemerov & Isakova, 2015, p. 95). val lambda1 = {a:Int, b:Int -> a + b} Wanneer er slechts een parameter wordt gespecifieerd, dan kan die in de body benaderd worden via het it-statement in plaats van via zijn naam. Verder mag het datatype van de parameters weggelaten worden indien de compiler het via inferrence kan afleiden. 4.1.8.3. Ter vervanging van anonieme klassen De belangrijkste doelstelling van lambda-expressies vinden we in het beknopter en leesbaarder maken van de code. Events worden in Java bijvoorbeeld heel vaak afgehandeld middels het maken van 43 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? een anonieme klasse, waarin een of meerdere methodes beschrijven welke functionaliteit er precies verwacht wordt. Dergelijke anonieme klassen vragen meestal een aanzienlijke hoeveelheid boilerplate code en worden dikwijls op meerdere plekken herhaald (Jemerov & Isakova, 2015, p. 93). Het voorbeeld toont dat voor een onClickListener op een button, en illustreert hoe Kotlin die syntax vereenvoudigt. //Java button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(“Button: “, “Has been clicked”); } }); //Kotlin button.setOnClickListener({ println(“Button has been clicked”) }) In het voorbeeld zal de Kotlin-syntax compileren naar dezelfde code als Java. Er wordt met andere woorden achter de schermen ook een anonieme klasse aangemaakt (Jemerov & Isakova, 2015, p. 117). Kotlin voegt wel nog een extra performantie toe: wanneer de lambda-expressie geen variabelen aanspreekt van de functie waarin ze is gedeclareerd, dan wordt een instantie van de anonieme klasse gedeeld over meerdere aanroepen. 4.1.8.4. Member references Sommige lambda’s kunnen ook genoteerd worden als member references. Zij voorzien de mogelijkheid om via een verkorte syntax functies op te stellen die exact een methode van een object aanroepen of exact een property van een object benaderen. De notatie specifieert de klasse die men wenst aan te spreken, gevolgd door een dubbele dubbele punt en eindigend met het te benaderen onderdeel van die klasse. Naam van de klasse {Klasse::member} Member: functie of property Figuur 7: Notatie van een member reference in Kotlin (Jemerov & Isakova, 2015, p. 102). Het voorbeeld toont een klasse ‘Student’ met drie velden: firstname, name en averagePoints. Er worden twee instanties van die klasse aangemaakt en in een lijst gestopt. Vervolgens wordt via de specifieke Kotlin-functie maxBy de student met het hoogste gemiddelde uit de lijst gehaald. maxBy krijgt als argument een member reference. Hetzelfde wordt daarna ter vergelijking nog eens overgedaan met een lambda. 44 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Student.kt data class Student(val firstname:String, val lastname:String, val averagePoints:Int) MainActivity.kt val student1 = Student(“John”, “Doe”, 16) val student2 = Student(“Jane”, “Doe”, 12) val students = listOf(student1, student2) //Lambda val max1 = students.maxBy { s:Student -> s.averagePoints } //Member reference val max2 = students.maxBy { Student::averagePoints } //Student John //Student John 4.1.9.Visibility modifiers Visibility modifiers geven aan in welk deel van de applicatie een bepaalde klasse, functie of property beschikbaar is. De onderstaande lijst geeft een overzicht van de beschikbare visibility modifiers in Java en hun toegankelijkheid (“Controlling Access to Members of a Class”, s.d.): Modifier Toegankelijk in klasse Toegankelijk in package Toegankelijk in subklassen Toegankelijk overal Public Ja Ja Ja Ja Protected Ja Ja Ja Neen Geen modifier Ja Ja Neen Neen Private Ja Neen Neen Neen Figuur 8: Visibility modifiers in Java (“Controlling Access To Members of a Class”, s.d.). De visibility modifiers van Kotlin vertonen zeer sterke gelijkenissen met die van Java. Er wordt enkel een internal-modifier toegevoegd ter vervanging van de niet-gespecifieerde modifier. Onderstaande tabel geeft een overzicht (Leiva, 2015, p. 50): Modifier Toegankelijk in klasse Toegankelijk in package Toegankelijk in subklassen Toegankelijk overal Public Ja Ja Ja Ja 45 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Modifier Toegankelijk in klasse Toegankelijk in package Toegankelijk in subklassen Toegankelijk overal Protected Ja Ja Ja Neen Internal Ja Ja Neen Neen Private Ja Neen Neen Neen Figuur 9: Visibility modifiers in Kotlin (Leiva, 2015, p. 50). Wanneer in Kotlin geen visibility modifier wordt opgegeven, dan wordt public als default gebruikt (“Visibility Modifiers”, s.d.). 4.1.10. Statische methodes en properties Er bestaat geen concept van statische methodes en properties in Kotlin. De taal beschikt immers over de mogelijkheid om hen top-level te definiëren en ziet dat als een volwaardig alternatief (Hariri, 2012). Wanneer die functionaliteit toch niet volstaat, kan een klasse ook nog steeds voorzien worden van een zogenaamd companion object. Dat is een object met properties en functies die, net zoals statische expressies in Java, via de dotnotatie rechtstreeks op de klasse kunnen worden aangeroepen. Het volgende voorbeeld toont dat aan. Student.kt class Student() { companion object { val url = “http://www.howest.be/students.json” } } MainActivity.kt println(Student.url) 4.1.11. //http://www.howest.be/students.json Singletons Een singleton is een klasse waarvan slechts een object kan worden gemaakt (“Singleton (ontwerppatroon)”, s.d.). Dat is een populair patroon dat in Android bijvoorbeeld aangewend wordt voor het aanmaken van een connectie met de interne SQLite-database. Kotlin voorziet in een specifieke en eenvoudige syntax die het schrijven van singletons makkelijker maakt. De code illustreert een singleton-klasse ‘Connection’ met een functie connect. 46 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? object Connection { fun connect() { println(“Connection made”) } } 4.2. Voor Android Kotlin ondersteunt Java 6 en alle nieuwere varianten van dat programmeerplatform. Dat maakt de alternatieve taal van JetBrains ook geschikt voor de ontwikkeling van Android-applicaties (Hearn, 2015). Googles besturingssysteem maakt op dit moment namelijk nog steeds gebruik van de open source Apache Harmony-implementatie, die, zoals reeds werd aangetoond in het eerste hoofdstuk, het midden houdt tussen Java 6 en Java 7 (Wharton, 2015a). De ontwerpers van Kotlin voorzien, naast de eigenlijke taal, verschillende gereedschappen die de performantie bij de ontwikkeling van Android-applicaties moeten verhogen. 4.2.1.Kotlin Android Extensions De Kotlin Android Extensions hebben als enige doel de communicatie tussen de XML-lay-outbestanden en hun achterliggende code te vereenvoudigen. Ze creëren automatisch een lijst met properties waarmee de Views in XML rechtstreeks aangesproken kunnen worden. Die properties ontlenen hun naam aan het id-attribuut van de View. Op die manier wordt de Java-syntax, waarbij de functie findViewById gecombineerd wordt met een expliciete cast naar het juiste datatype, overbodig (Zhulanow, 2015). In het bijgevoegde voorbeeld wordt de Kotlin-notatie vergeleken met de overeenkomstige syntax in Java. MainActivity.kt //Kotlin helloWorld.text = “Hello world!” SecondaryActivity.java //Java TextView helloWorld = (TextView) findViewById(R.id.helloWorld); helloWorld.setText(“Hello world!”); Onderhuids zal die plug-in alle propertyaanroepen vervangen door hun overeenkomstige Java-variant (dus wel met findViewById). Bovendien wordt elke aanroep van een View in een cache bijgehouden, waardoor een nieuwe benadering sneller kan worden uitgevoerd. Die verbeterde syntax brengt met andere woorden geen technisch performantieverlies met zich mee ten opzichte van Java (Leiva, 2015, p. 52). 47 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 4.2.2.Java-naar-Kotlin-converter JetBrains maakte samen met Kotlin ook een converter die Java-code omzet naar overeenkomstige Kotlin-syntax. Hij doet zijn werk vrij correct bij kleine en eenvoudige klassen. Men mag hem evenwel niet beschouwen als een gereedschap om volledige applicaties om te zetten naar Kotlin. De code die de converter produceert, is immers vaak niet de meest performante en bij omzettingen van grote klassen sluipen hier en daar fouten binnen (Hearn, 2015). 4.2.3.Anko Anko (AndroidKotlin) is een eveneens door JetBrains ontwikkelde bibliotheek die de Android-API uitbreidt met specifiek op Kotlin gerichte functionaliteit (Jemerov & Isakova, 2015, p. 60). Het maakt daartoe enkel gebruik van extension functions (uitbreidingsfuncties) op de bestaande klassen. De library wil in eerste instantie vooral het creëren van lay-outs vereenvoudigen. Daarnaast voorziet het ook oplossingen voor intents, toast messages, asynchrone taken en SQLite-connecties. De belangrijkste mogelijkheden worden in dit hoofdstuk behandeld. 4.2.3.1. Lay-outs Standaard wordt de userinterface van een Android-applicatie geschreven met behulp van XML-code. Die werkwijze heeft volgens de ontwikkelaars van Anko (s.d) evenwel een aantal nadelen: ze detecteert geen schrijffouten, vereist veel herhaalde code en het parsen van de XML vraagt veel kracht van de CPU en bijgevolg ook batterijtijd. Een mogelijke, maar weinig elegante oplossing is het programmatorisch beschrijven van de UI in de Activity of in het Fragment. Anko biedt hier evenwel een uitweg voor: het laat toe om de lay-out zonder alle voorgaande nadelen te beschrijven in code middels een specifieke syntax (“Anko”, s.d.). Net omwille van die laatste eigenschap wordt de library ook wel een DSL of domain specific language genoemd. DSL’s zijn programmeertalen die zich enkel richten op het oplossen van een specifiek probleem, in de meeste gevallen moeilijk leesbare syntax. Ze worden vaak gedefinieerd binnen de API van een bestaande programmeertaal, in het geval van Anko is dat Kotlin (Ruiz & Bay, 2008). Het voorbeeld toont hoe de lay-out van een Activity kan worden gedefinieerd in diens onCreatemethode. Er wordt een LinearLayout aangemaakt met een verticale oriëntatie en lay-outparameters voor de breedte en de hoogte. Daarbinnen worden een TextView, EditText en Button gedefinieerd. Bij het klikken op de Button wordt een Toast getoond met de waarde die in de EditText werd ingevuld. override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) linearLayout { orientation = LinearLayout.VERTICAL lparams { width = matchParent height = matchParent } 48 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? textView(“Please fill in your name”) val name = editText { hint = “Name” } val button = button(“Say Hello”) { onClick { toast(“Hello ${name.text}”) } } } } Figuur 10: Voorbeeld van een Anko-layout. Het definiëren van volledige lay-outs in de onCreate-methode van een Activity kan de leesbaarheid van de code nadelig beïnvloeden. Daarom is het ook mogelijk om ze als een aparte klasse te definiëren die in de onCreate-methode wordt aangesproken (Shrestha, 2015). De onderstaande code toont een klasse ‘MainLayout’ waarin de lay-out van MainActivity wordt gedefinieerd. 49 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? MainLayout.kt class MainLayout : AnkoComponent<MainActivity> { override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) { return linearLayout { orientation = LinearLayout.VERTICAL lparams { width = matchParent height = matchParent } textView(“Please fill in your name”) val name = editText { hint = “Name” } val button = button(“Say Hello”) { onClick { toast(“Hello ${name.text}”) } } } } } MainActivity.kt override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) MainLayout().setContentView(this) } Anko biedt dus een eigen, verkorte syntax voor alle Views die standaard aanwezig zijn in Android. Verder voorziet het ook alternatieven voor een aantal veelgebruikte bibliotheken met lay-outelementen zoals de Android RecyclerView en de Android CardView. Aangezien de op Kotlin gebaseerde DSL volledig is opgebouwd uit extension functions op de bestaande Android-API, betekent dat dat applicatieontwikkelaars er zelf ook kunnen bijmaken (“Anko”, s.d.). Op die manier kunnen ook Views uit bibliotheken van derden worden omgezet naar een overeenkomstige Anko-variant. In het bijhorende voorbeeld wordt de verzameling van beschikbare Views uitgebreid met de RubberLoaderView van Artisom Grintsevich (https://github.com/greenfrvr/rubber-loader). Dat gebeurt middels een extension function op de klasse ViewManager. Vanaf dat moment kan de View via de gespecifieerde functienaam gebruikt worden in Anko-code. //Extension function inline fun ViewManager.rubberLoaderView(init: RubberLoaderView.() -> Unit) = ankoView({ RubberLoaderView(it) }, init) 50 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? //MainActivity class class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) linearLayout { lparams { width = matchParent height = matchParent } val loader = rubberLoaderView { lparams { width = matchParent height = matchParent } gravity = Gravity.CENTER } loader.startLoading() } } } 4.2.3.2. Lay-outs: de achtergrond Zoals reeds vermeld werd, is Anko volledig opgebouwd uit extension functions bovenop de API’s van Android. Ze worden gecreëerd volgens het builderpatroon, dat toelaat om complexe objecten niet in een keer via een constructor, maar wel stap voor stap op te bouwen (Frankel, 2013). Het volgende voorbeeld illustreert dat via een TextView-element. textView { lparams{ width = matchParent } text = “Hello World” gravity = Gravity.CENTER textColor = R.color.highlighted_text_material_dark backgroundColor = R.color.colorPrimaryDark } In de achtergrond maakt de functie textView een nieuwe instantie van TextView aan zonder enige parameters. De code tussen de accolades is een lambda-expressie die bij de instantiatie wordt uitgevoerd en die de attributen of properties van het TextView-object stap voor stap instelt (“Type-Safe Builders”, s.d.). 51 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? De eigenlijke functie textView is een extension function bovenop de ViewManager-API van Android. In de body wordt een nieuwe instantie van TextView aangemaakt. Vervolgens wordt de meegeleverde lambda-expressie init uitgevoerd op dat object om de attributen of properties ervan in te stellen. Vervolgens wordt het aangemaakte en geïnitialiseerde object via de return teruggegeven (“Type-Safe Builders”, s.d.). fun ViewManager.textView(init: TextView.() -> Unit): TextView { val textView = TextView(context) textView.init() return textView } De voorbeelden tonen aan dat de Anko-code in de achtergrond herleid wordt tot statements die de reguliere Android-API’s aanspreken (“Anko”, s.d.). 4.2.3.3. Intents Applicaties die hevig steunen op Intents, hebben heel vaak te maken met veelvuldig herhaalde statements: het Intent moet aangemaakt worden, eventuele parameters dienen ingesteld te worden en vervolgens moet het tot uitvoering gebracht worden. Anko voorziet in kortere syntax die het geheel een stuk werkbaarder maakt (“Anko Advanced topics”, s.d.). Het voorbeeld toont de code die vereist is om een Activity op te starten met parameters. Die syntax wordt vervolgens vergeleken met diegene die nodig is om hetzelfde te bereiken wanneer men enkel gebruikmaakt van de Android-API. //Kotlin startActivity<SecondaryActivity>(“firstname” to “Kristof”, “lastname” to “Colpaert”) //Android val intent = Intent(this, javaClass<SecondaryActivity>()) intent.putExtra(“firstname”, “Kristof”) intent.putExtra(“lastname”, “Colpaert”) startActivity(intent) Daarnaast beschikt Anko ook over verkorte schrijfwijzen voor veelgebruikte Intents zoals het verzenden van een e-mail en het openen van een browser. Het bijgevoegde voorbeeld overloopt een aantal voorbeelden (“Anko Advanced topics”, s.d.). //Start call activity buttonCall.onClick { makeCall(“003290000000”) } //Start browser activity buttonBrowse.onClick { browse(“http://www.google.be”) } //Start sharing activity buttonShare.onClick { share(“This is a test with Anko.”, “Anko subject”) } 52 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? //Start email activity buttonEmail.onClick { email(“[email protected]”, “Anko subject”, “This is a test with Anko.”) } 4.2.3.4. Argumenten voor Fragments Argumenten worden bij het instantiëren van Fragments typisch niet meegegeven via de constructor, maar wel in een Bundle-object dat via de setArguments-functie wordt ingesteld. Ook die operatie vraagt de nodige stappen: de Bundle moet geïnitialiseerd worden, argumenten moeten een voor een toegevoegd worden en ten slotte moet het geheel nog gelinkt worden aan het Fragment-object. Anko tracht dat een heel stuk te vereenvoudigen via een withArguments-functie die toelaat om een Fragment meteen met de juiste argumenten-Bundle te instantiëren (“Anko Advanced topics”, s.d.). Het voorbeeld toont de verschillen tussen Anko en Android. //Anko val mainFragment1 = MainFragment().withArguments(“firstname” to “Kristof”, “lastname” to “Colpaert”) fragmentManager.beginTransaction().add(containerId, mainFragment1).commit() //Android val mainFragment2 = MainFragment(); val bundle = Bundle() bundle.putString(“firstname”, “Kristof”) bundle.putString(“lastname”, “Colpaert”) mainFragment2.arguments = bundle fragmentManager.beginTransaction().add(containerId, mainFragment2).commit() 4.2.3.5. Services Anko maakt heel wat Android-services beschikbaar onder een eenvoudiger te onthouden naam. De bibliotheek past dat onder andere toe op de notificatieservice en de sensorservice (“Anko Advanced topics”, s.d.). Onderstaande code illustreert hoe men de vibratiedienst aanspreekt om het toestel gedurende een seconde te laten vibreren. //Anko vibrator.vibrate(1000) //Android val vibrator1:Vibrator = getSystemService(VIBRATOR_SERVICE) as Vibrator; vibrator1.vibrate(1000) 4.2.3.6. Qualifiers Binnen Android worden qualifiers aangewend om verschillende resources te definiëren naargelang de karakteristieken van het toestel waarop de applicatie draait. Op die manier kan men bijvoorbeeld voor de portretmodus van een toepassing andere afbeeldingen specifiëren dan voor de landschapsvariant. 53 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? De gebruikte qualifier zou in dat geval de oriëntatie van het scherm zijn. Anko biedt via de configurationfunctie een mogelijkheid om ook in code qualifiers te specifiëren. Bepaalde code zal dan enkel uitgevoerd worden wanneer aan de opgelegde voorwaarden voldaan wordt (“Anko Advanced topics”, s.d.). Anko bezit qualifiers voor onder meer de Android-versie van het toestel, de grootte van het scherm en de oriëntatie ervan. In de voorbeeldcode zal het toestel gedurende een seconde vibreren wanneer het zich bevindt in portretmodus. configuration(orientation = Orientation.PORTRAIT) { vibrator.vibrate(1000) } 4.2.3.7. Toasts en Dialogs Toasts zijn in Android korte berichten die gedurende een welbepaalde tijd onderaan op het scherm verschijnen. Men kan er niet mee interageren. Dialogs zijn op hun beurt pop-ups die verschijnen op het scherm en die een bepaalde actie verwachten. Ze kunnen de gebruiker bijvoorbeeld vragen om bepaalde gegevens te voorzien. Ook voor Toasts en Dialogs voorziet Anko een verkorte syntax ten opzichte van Android (“Anko Advanced topics”, s.d.). Het voorbeeld vergelijkt beiden met de overeenkomstige standaardcode. button(“Toast”){ onClick { //Anko toast(“Hello world”) //Android Toast.makeText(context, “Hello world”, Toast.LENGTH_SHORT).show() } } button(“Dialog”) { onClick { println(“hier”) //Anko alert(“Yes or no?”, “Dialog”) { positiveButton(“Yes”) { println(“Yes”) } negativeButton(“No”) { println(“No”) } }.show() //Android val listener = DialogInterface.OnClickListener { dialogInterface, i -> when(i) { DialogInterface.BUTTON_POSITIVE -> println(“Yes”) DialogInterface.BUTTON_NEGATIVE -> println(“No”) } } 54 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? val builder = AlertDialog.Builder(context) builder.setTitle(“Dialog”) .setMessage(“Yes or no?”) .setPositiveButton(“Yes”, listener) .setNegativeButton(“No”, listener) } } 4.2.3.8. Asynchrone taken Android laat toe om hardware-intensieve taken toe te wijzen aan een worker thread die los staat van de UI thread. Het uitvoeren van die taken op de UI thread zou er immers voor zorgen dat de applicatie gedurende een bepaalde periode geen antwoord biedt op de acties van de gebruiker. Klassen die overerven van AsyncTask of AsyncTaskLoader, implementeren functionaliteit die hen toelaat om code uit te voeren op een worker thread en het resultaat ervan terug te geven aan de UI thread (“Processes and Threads”, s.d.). Applicaties die sterk steunen op communicatie met het internet, bezitten logischerwijs heel wat klassen die overerven van AsyncTask of AsyncTaskLoader. Dat brengt niet enkel extra complexiteit met zich mee, maar ook bijkomende risico’s. Het is immers niet makkelijk om die klassen te implementeren zonder dat daarbij neveneffecten optreden. Een Activity kan bijvoorbeeld reeds onderbroken worden tijdens het uitvoeren van de asynchrone taak. In dergelijke gevallen zal die taak dan ook crashen. Anko probeert die complexiteit het hoofd te bieden via een concept dat het uitvoeren van code op een worker thread sterk vereenvoudigt. (Leiva, 2015, p. 30). Het voorbeeld toont hoe een methode async een lambda-expressie die de uit te voeren taak beschrijft, ontvangt. In dit geval moet data van een API afgehaald worden, om ze vervolgens naar een String om te zetten. Ten slotte wordt de UI thread aangesproken via de uiThread-functie om zo de lay-out up te daten met het resultaat van de asynchrone taak. //Anko async() { val url = “http://jsonplaceholder.typicode.com/posts” val inputStream = URL(url).openStream() val result = Scanner(inputStream, “UTF-8”).useDelimiter(“\\A”).next() uiThread { resultTextView.text = result } } De vergelijkbare code in Android wordt gesplitst over twee klassen, namelijk LoadApiData en MainActivity. Aangezien binnen de AsyncTask (LoadApiData) enkel de methode onPostExecute taken op de UI thread kan uitvoeren, moet er een link met de userinterface meegegeven worden vanuit MainActivity om de lay-out te updaten. In het onderstaande voorbeeld wordt daarom een referentie meegegeven naar de TextView waarin het resultaat moet verschijnen. 55 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? LoadApiData.kt class LoadApiData(val resultView: TextView) : AsyncTask<Void, String, String>() { override fun doInBackground(vararg params: Void): String? { val url = “http://jsonplaceholder.typicode.com/posts” val inputStream = URL(url).openStream() val result = Scanner(inputStream, “UTF-8”).useDelimiter(“\\A”). next() inputStream.close() return result } override fun onPostExecute(result: String?) { resultView.text = result } } MainActivity.kt //Android val result = LoadApiData(resultTextView).execute() 4.2.3.9. SQLite SQLite is een lichtgewicht databaseplatform dat uiterst geschikt is voor gebruik in mobiele applicaties. Net omwille van dat voordeel rust Google het Android-framework dan ook standaard uit met het systeem. De meegeleverde basis-API’s hebben evenwel een aantal beperkingen: objecten moeten omgezet worden naar ContentValues of geparst worden vanuit een Cursor (Leiva, 2015, p. 64). Bovendien kan multithreading voor extra uitdagingen zorgen met betrekking tot concurrentiële toegang tot de database (“Anko Loves SQLite”, s.d.). Die hindernissen zorgen ervoor dat applicatieontwikkelaars voor hun lokale databaseopslag al snel terugvallen op externe bibliotheken en Object Relational Mappers. Maar ook die ORM’s komen niet zonder nadelen: vaak overladen ze het systeem met een hoop functies die niet gebruikt worden (“Anko Loves SQLite”, s.d.). Anko voorziet een ManagedSQLiteOpenHelper-klasse, die als alternatief voor de ingebouwde SQLiteOpenHelper het benaderen van het interne databasessysteem een heel stuk eenvoudiger maakt (Leiva, 2015, p. 64). Zoals het voorbeeld aantoont, moeten databaseklassen die overerven van de ManagedSQLiteOpenHelper de abstracte methodes onCreate en onUpgrade implementeren. Die eerste wordt uitgevoerd wanneer de applicatie voor het eerst wordt opgestart, die tweede telkens wanneer de applicatie een nieuwe versie van de database introduceert. Dat is bijvoorbeeld het geval wanneer het schema van de tabellen wijzigt. Het geheel wordt geïntegreerd in een singleton-patroon zodat er slechts een connectie met de database wordt aangemaakt. object DatabaseHelper : ManagedSQLiteOpenHelper(App.instance!!, “StudentApp”, null, 1) { 56 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? override fun onCreate(database: SQLiteDatabase) { onUpgrade(database, 0, 1) } override fun onUpgrade(database: SQLiteDatabase, oldVersion: Int, newVersion: Int) { var tempOldVersion = oldVersion while(tempOldVersion < newVersion) { when(tempOldVersion) { 0 -> { database.createTable(“Students”, true, StudentsTableContract.ID to INTEGER + PRIMARY_ KEY + AUTOINCREMENT, StudentsTableContract.FIRSTNAME to TEXT, StudentsTableContract.LASTNAME to TEXT, StudentsTableContract.EMAIL to TEXT) } } tempOldVersion++ } } } De volgende code illustreert hoe een instantie van SQLiteDatabase kan worden verkregen van de DatabaseHelper en hoe Anko bewerkingen op databases een heel stuk vereenvoudigt. Zo vereist het toevoegen van data bijvoorbeeld niet langer het gebruik van complexe ContentValues. Elk in te voeren veld wordt daarentegen beschreven door een key-valuepaar, waarbij de key de naam van de kolom is en de value de eigenlijke waarde. Beiden worden met elkaar verbonden door middel van een tostatement (“Anko Loves SQLite”, s.d.). val db = DatabaseHelper.writableDatabase db.insert(“Students”, StudentsTableContract.ID to 1, StudentsTableContract.FIRSTNAME to “Kristof”, StudentsTableContract.LASTNAME to “Colpaert”, StudentsTableContract.EMAIL to “[email protected]. be”) Ook voor het opvragen van gegevens uit de SQLite-database heeft Anko een alternatieve syntax. De select-functie ontvangt als argument de naam van de tabel die men wenst aan te spreken. Vervolgens kunnen een aantal optionele functies opgeroepen worden, waaronder where, orderBy, groupBy, limit, having en distinct. Ten slotte kan het resultaat als een lijst of als een object geparst worden met de functies parseSingle, parseOpt en parseList. De eerste methode behandelt sowieso een rij, terwijl de tweede ook null kan teruggeven indien er geen data ontvangen worden. Elk van die drie parsefuncties krijgen als argument een instantie mee van een klasse die overerft van RowParser. Die klasse implementeert de abstracte functie parseRow, waarin een rij, voorgesteld als een array van kolommen, wordt geparst 57 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? naar een object van het juiste type. Die manier van werken zorgt ervoor dat applicatieontwikkelaars niet langer Cursors rij voor rij en kolom voor kolom moeten parsen, zoals dat het geval is in de standaardAPI van Android (“Anko Loves SQLite”, s.d.). De voorbeeldcode toont hoe een specifieke student in de klasse MainActivity wordt opgevraagd. De Cursor wordt via de StudentParser-klasse omgezet naar een object van het type ‘Student’. Student.kt data class Student(val firstname:String, val lastname:String, val email:String) StudentParser.kt class StudentParser : RowParser<Student> { override fun parseRow(columns: Array<Any>): Student { return Student(columns[1] as String, columns[2] as String, columns[3] as String) } } MainActivity.kt val db = DatabaseHelper.readableDatabase val student = db.select(“Students”).where(“(_id = {userId})”, “userId” to 1).parseSingle(StudentParser()) 58 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 5.De voordelen van Kotlin voor Android-ontwikkelaars 59 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? De vorige hoofdstukken wezen reeds uit dat Kotlin een reeks mogelijkheden bezit die ook nuttig zijn voor Android-ontwikkelaars. In dit onderdeel worden de voordelen van de taal en haar extensies opgesomd, specifiek gericht op het maken van Android-applicaties en zonder daarbij al te diep in te gaan op de technische kant. 5.1. Perfecte integratie met IDE JetBrains is niet enkel de organisatie achter Kotlin, maar ook de grondlegger van de IntelliJ IDEA-IDE, een populair ontwikkelingsplatform voor Java-applicaties. Android Studio, de officiële programmeeromgeving voor Android, is een afgeleide daarvan en bezit dus heel wat technologie die ontwikkeld werd door JetBrains (Jemerov, 2013). Net die sterke band maakt het creëren van Kotlinapplicaties in Android Studio heel eenvoudig: JetBrains voorziet een plug-in die in enkele stappen Android-projecten configureert met Kotlin. Verder bezit die extensie eveneens een uitgebreide module met codesuggesties, een compiler die Kotlin-code omzet naar Java bytecode en een converter die Java-syntax herschrijft naar Kotlin (Leiva, 2015, p. 4). Android Studio heeft met andere woorden via JetBrains een uitgebreide set gereedschappen aan boord ter ondersteuning van Kotlin-projecten. Er is ook een plug-in voor de Eclipse-IDE, een andere populaire programmeeromgeving waarin Android-applicaties worden geschreven. De ontwikkeling ervan loopt evenwel steeds achter op die van eerdergenoemde IDE’s (Leiva, 2015, p. 9). 5.2. Lage leercurve Voor ontwikkelaars die vertrouwd zijn met de Java-syntax, is starten met Kotlin geen grote stap. De basisconcepten van beide talen zijn immers grotendeels dezelfde (Jemerov & Isakova, 2015, p. 4). Kotlin implementeert wel een aantal functionele concepten die niet aanwezig zijn in Java, maar blijft bovenal een objectgeoriënteerde programmeertaal. Bovendien worden er geen verplichtingen opgelegd met betrekking tot het gebruik van die mogelijkheden uit het functioneel programmeren. Verder maken ook de intuïtieve syntax, goede leesbaarheid en beknoptheid Kotlin eenvoudig om aan te leren (Hearn, 2015). 5.3. Lichtgewicht programmeertaal met weinig runtimekosten De standaardbibliotheek van Kotlin bestaat voor het overgrote deel uit gerichte uitbreidingen van de Java-API. Er worden geen fundamenteel nieuwe concepten geïntroduceerd. De taal tracht enkel de zogenaamde missing links in Java te dichten. Verder worden de functionele constructies die Kotlin ondersteunt reeds bij het compileren omgezet naar een imperatieve versie die de Java Virtual Machine, Dalvik Virtual Machine of Android Runtime kunnen uitvoeren. Dat zorgt ervoor dat de kost of belasting die Kotlin tijdens het uitvoeren van de applicatie oplegt minimaal blijft (Hearn, 2015). Zoals reeds werd aangegeven, is het aantal methodes van een applicatie van cruciaal belang binnen Android. Projecten die een maximale ondersteuning willen bieden voor oudere versies van het platform en dus geen multidexing gebruiken, zijn beperkt tot maximaal 65.563 methodes. Het aantal functies die een bibliotheek of alternatieve taal toevoegt aan het totaal, is dus van cruciaal belang binnen Android. Kotlin introduceert zelf ongeveer zevenduizend methodes (Leiva, 2015). 60 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? In vergelijking met andere populaire alternatieve Java-talen zoals Groovy, Scala en Clojure zijn de bijkomende kosten van Kotlin relatief klein. De volgende tabel toont het aantal methodes en de grootte in kB van de bibliotheken van elk van de eerdergenoemde talen en vergelijkt ze met de gegevens van Kotlin. De berekeningen werden gemaakt via de website van Sebastiano Gottardo (http://www. methodscount.com) en tonen duidelijk aan dat de library van Kotlin ettelijke malen kleiner is dan die van zijn concurrenten. Bibliotheek Aantal methodes Grootte in kB Kotlin 1.0.0-rc-1036 6961 706 Scala 2.11.7 50811 5746 Groovy 2.4.6 28802 4559 Clojure 1.8.0 16023 3623 Figuur 11: Vergelijking van het aantal methodes tussen Kotlin en andere alternatieve Java-talen. 5.4. Null-veiligheid reduceert fouten Een van de belangrijkste pijlers van Kotlin is het inbouwen van null-veiligheid door te werken met veranderlijke en onveranderlijke variabelen. Dat onderscheid maakt dat potentiële null-fouten reeds bij het compileren worden ontdekt en niet tot crashes kunnen leiden bij het uitvoeren van de applicatie. Wanneer de toepassing faalt bij de eindgebruiker, dan kan dat er immers toe leiden dat hij haar niet meer gebruikt (Jemerov & Isakova, 2015, p. 7). 5.5. Kotlin verhoogt productiviteit Kotlin voegt functionaliteit toe die veelgebruikte programmeerstructuren in de Java- en Androidplatforms een heel stuk eenvoudiger maakt. Klassen worden bijvoorbeeld automatisch uitgerust met properties die getters en setters overbodig maken, terwijl anonieme klassen als event handlers kunnen worden vervangen door lambda-expressies. Verder helpen ook uitbreidingen zoals de Kotlin Android Extensions en Anko alsook de gereedschappen van de JetBrains IDE’s bij het schrijven van applicaties. Al die zaken verhogen stuk voor stuk de productiviteit van de ontwikkelaar en helpen aldus om sneller betere applicaties te maken (Wharton, 2015b, p. 1). 5.6. Ondersteuning voor Java 6 Kotlin baseert zich op de Java-versies (6 en 7) die vandaag nog steeds het meest gebruikt worden door Android-toestellen. Dat betekent dat ontwikkelaars kunnen gebruikmaken van alle nieuwe mogelijkheden die een moderne taal met zich meebrengt, zonder dat ze zich zorgen hoeven te maken over de compatibiliteit van hun applicaties met oudere toestellen (Jemerov & Isakova, 2015, p. 9). 61 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 5.7. Ondersteuning vanuit JetBrains en gegarandeerde toekomst Hoewel Kotlin open source is en iedereen bijdrages kan leveren tot de taal en haar gereedschappen, werden de belangrijkste krijtlijnen ervan toch uitgetekend door een commerciële organisatie. Binnen JetBrains werkt een twintigkoppig team voltijds aan toevoegingen en verbeteringen voor de toekomst (Breslav, 2016). Die commerciële inslag brengt met zich mee dat de taal sneller evolueert dan zuivere open sourceprojecten die steunen op de goodwill van een reeks vrijwilligers. Tenslotte heeft JetBrains er ook alle baat bij dat Kotlin weerklank vindt binnen het hele Java- en Android-gebeuren, aangezien het succes ervan allicht ook zal leiden tot meer verkochte versies van hun op Kotlin gerichte IDE’s en gereedschappen (Beust, 2011). JetBrains gaf bij de lancering van Kotlin aan dat het voorziet in een langdurige achterwaartse compatibiliteit. Dat wil zeggen dat nieuwere varianten van de Kotlin-compiler zullen kunnen blijven werken met oudere code en dat in projecten nieuwe syntax kan worden gemengd met oudere (Breslav, 2016). Bovendien gebruikt het de taal ook in de ontwikkeling van zijn eigen producten (De Simone, 2016). Met die zet garandeert het in Tsjechië gebaseerde bedrijf ook meteen de toekomst van Kotlin. 5.8. Interoperabiliteit De interoperabiliteit met Java is een punt waarop JetBrains heel hard heeft ingezet. De term geeft aan dat Java-code zonder enig probleem kan worden aangesproken vanuit Kotlin en dat het omgekeerde even naadloos verloopt (Leiva, 2015, p. 5). Die eigenschap geeft de ontwikkelaar een zekere vrijheid: hij kiest zelf hoeveel Kotlin hij in zijn projecten betrekt. Een applicatie hoeft immers niet noodzakelijk volledig in deze taal opgebouwd te zijn: toepassingen kunnen gradueel herschreven worden of enkel nieuwe functionaliteiten kunnen genoteerd worden in Kotlin (Hearn, 2015). 62 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 6.De nadelen van Kotlin voor Android-ontwikkelaars 63 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Naast voordelen kampt Kotlin ook met een aantal nadelen. Dit hoofdstuk somt een aantal redenen op waarom men de taal beter niet gebruikt in Android-applicaties. 6.1. Nieuwe taal, nieuwe termen Hoewel Kotlin kan schermen met een relatief lage leerdrempel, blijft het toch een nieuwe syntax met eigen kenmerken en karaktertrekken. Het zal voor ontwikkelaars bijgevolg nog steeds de nodige tijd vragen om alle best practices van de taal onder de knie te krijgen en die in de praktijk te gebruiken (Wharton, 2015b, p. 20). 6.2. Null-veiligheid valt weg door interoperabiliteit Het onderscheid tussen variabelen die null kunnen bevatten en variabelen die dat niet kunnen, maakt Kotlin een taal die veilig is voor null-fouten of NullPointerExceptions. Wanneer echter gewerkt wordt met waarden die afkomstig zijn uit Java-code, dan valt die veiligheid volledig weg. Tenzij aangegeven via Nullable- of NotNull-annotaties, bezitten variabelen die uit Java-code komen, geen null-informatie. Binnen Kotlin worden de datatypes van dergelijke variabelen platformtypes genoemd. Aangezien het behoorlijk wat werk zou vergen om voor elk van hen te controleren of ze wel degelijk geen null-waarde bevatten, laat Kotlin de keuze aan de ontwikkelaar om ze te behandelen als een variabele die nullreferenties kan bevatten of als een variabele die dat niet kan. (Jemerov & Isakova, 2015, p. 141). Die werkwijze zorgt er dan wel voor dat niet elke variabele die afkomstig is uit Java, moet worden gecontroleerd op null-referenties, maar brengt wel met zich mee dat de NullPointerException-veiligheid niet langer gegarandeerd is. Wanneer een variabele immers niet gecontroleerd wordt voor gebruik en zij een null-waarde bevat, dan zal de applicatie tijdens het uitvoeren van die code crashen. Gegeven het feit dat zowel het Android-framework als de meeste externe bibliotheken geschreven zijn in Java, is dit een probleem dat in haast ieder project opduikt en de werking van de applicatie kan verstoren. 6.3. Benoemde argumenten maken deel uit van API Kotlin laat toe om bij het aanschrijven van een functie argumenten mee te geven via de naam van hun overeenkomstige parameter. Die techniek vereenvoudigt het aanroepen van functies met veel of optionele parameters en maakt de volgorde waarin argumenten worden doorgegeven van ondergeschikt belang. Dat impliceert wel dat de argumentnamen binnen Kotlin deel uitmaken van de API. Wanneer in de basisfunctie wijzigingen worden doorgevoerd in de argumentnamen, dan moeten die ook weerspiegeld worden in de aanroepende functies. Dat vergt extra oplettendheid van de ontwikkelaar (Jemerov & Isakova, 2015, p. 46). 6.4. De taal is nog niet volwassen Hoewel Kotlin het betastadium intussen heeft verlaten, zijn de taal en haar gereedschappen nog niet helemaal volwassen. Zo blijft de converter die Java naar Kotlin omzet nu en dan fouten produceren en crasht de Android Studio-plug-in nog te vaak. Bovendien laat ook de automatische aanvulling van 64 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? code het nog veel afweten (Hearn, 2015). Ten slotte heeft Anko, de bibliotheek met uitbreidingen die specifiek gericht zijn op Android, ook nog geen definitieve versie bereikt. 6.5. Wachten op Java 8 Midden maart 2016 gaf David Burke, de Vice President of Engineering van Google, al enkele details vrij over de toekomstige N-update van Android. Uit die informatie blijkt dat het besturingssysteem samen met de overgang op de OpenJDK-implementatie van Java ook versie 8 van dat programmeerplatform zal introduceren (Burke, 2016). Die variant brengt heel wat mogelijkheden mee die ook in Kotlin vervat zitten. Zo kan men bijvoorbeeld ook lambda-expressies schrijven of interfaces uitbreiden met methodes die een standaardimplementatie hebben. Bovendien compileert alles naar Java 8 bytecode, die efficiënter is dan de Java 6 bytecode die de Kotlin-compiler genereert (Hearn, 2015). Burke (2016) gaf in zijn mededeling ook aan dat de lambda-expressies, die standaard deel uitmaken van Java 8, achterwaarts compatibel zullen zijn met alle versies van Android tot en met Gingerbread (Android 2.3). Voor die oudere varianten van het besturingssysteem zal de Android-compiler specifieke functionaliteit voorzien die de lambda’s omzet naar overeenkomstige anonieme klassen in Java 6 bytecode. De meeste andere Java 8-nieuwigheden zullen daarentegen wel een privilege blijven voor Android N. Bijgevolg zal het nog steeds twee tot drie jaar duren alvorens een versie met ook die functionaliteit aan boord, een voldoende grote gebruikersbasis heeft. Toch wenden een aantal ontwikkelaars de nakende komst van Java 8 aan als argument tegen Kotlin en voor het gebruik van externe bibliotheken als tussenoplossing. Jake Wharton (2015b, p. 19) wijst er niettemin op dat Kotlin ook nog steeds heel wat voordelen heeft ten opzichte van Java 8, zoals een meer expressieve syntax en betere runtimemogelijkheden. 6.6. Kleine community De Kotlin-community is groeiende, maar momenteel nog relatief klein. Hoewel de interoperabiliteit garant staat voor een uitstekende samenwerking met Java-bibliotheken, zou het toch handiger en leuker werken zijn met specifieke Kotlin-libraries. Die zijn er wel, maar vormen een kleine minderheid ten opzichte van de massale hoeveelheid Java-bibliotheken. Bovendien is er nog maar weinig literatuur beschikbaar met betrekking tot het onderwerp. Er is een officiële onlinegids van JetBrains en er zijn twee boeken die een aantal best practices opsommen, maar verder zijn ontwikkelaars vooral aangewezen op blogs en onlinediscussieplatforms zoals Stack Exchange (http://www.stackexchange.com) en het forum van Kotlin (http://discuss.kotlinlang.org). Het feit dat Kotlin nog geen brede ondersteuning heeft, maakt dat commerciële organisaties de programmeertaal momenteel nog links laten liggen ten voordele van standaard-Android. Er is immers geen garantie dat iedereen in een ontwikkelingsteam overweg kan met de syntax en dat de programmeurs die de applicatie zullen onderhouden, dat ook kunnen (“A Quick Dive into Kotlin for Android”, 2015). Verder speelt ook het uitzicht op de toekomst een rol in die keuze: de huidige vorm van Android-programmeren zal allicht niet snel verlaten worden door Google, terwijl Kotlin bij tegenvallende (commerciële) resultaten gestopt kan worden door JetBrains. 65 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 6.7. Link met IDE’s van JetBrains Kotlin geniet een zeer sterke integratie met de programmeeromgevingen van JetBrains. De link met IDE’s van andere producenten is evenwel een stuk minder krachtig. Zo mist de plug-in die wordt voorzien voor Eclipse bijvoorbeeld heel wat finesses die de extensie van Android Studio of IntelliJ IDEA wel heeft. Hoewel Android Studio intussen de meestgebruikte ontwikkelomgeving is voor Androidapplicaties, blijft een deel van de programmeurs nog steeds zweren bij Eclipse. Voor hen is de IDEintegratie van Kotlin dan ook minder sterk (Leive, 2015, p. 9). 6.8. Extra kosten Hoewel de taal op zichzelf relatief weinig methodes telt en de runtimekosten niet hoog zijn, blijven ze hoe dan ook een extra belasting vormen voor het besturingssysteem en de hardware. Vooral op mobiele toestellen moet voor elke extra kost de afweging gemaakt worden of ze de moeite wel waard is. Volgens Jake Wharton (2015b, p1) komt Kotlin dan ook het best tot zijn recht in complexe projecten, waar zijn belasting relatief gezien beperkt is en zijn syntaxvoordelen het grootst zijn. 6.9. Tegendraadsheid Kotlin Net zoals veel andere talen heeft Kotlin nog een aantal scherpe of onlogische kantjes die het programmeren bemoeilijken. Zo is bijvoorbeeld overerving niet mogelijk in combinatie met dataklassen (Hearn, 2015). Andrey Breslav (2015), de projectleider van Kotlin binnen JetBrains, geeft aan dat die restrictie een noodzakelijk kwaad is om een overervingsproblematiek te voorkomen. De automatische implementatie van de equals- en copy-methodes zou bij overerving immers voor ideologische vraagstukken zorgen: moeten twee objecten van overervende klassen bijvoorbeeld gelijk zijn indien hun gemeenschappelijke velden dezelfde waarden hebben? Breslav erkent dat het beperken van de overerving geen ideale oplossing is. Hij ziet het dan ook als een tijdelijke uitweg die een snelle release van versie 1.0 van Kotlin mogelijk maakt, maar hij beseft ook dat voor volgende versies een meer passend antwoord zal moeten worden gevonden. Ook wat betreft het casten van numerieke datatypes vertoont Kotlin ietwat complex en afwijkend gedrag ten opzichte van Java. Een variabele van het datatype Integer laat zich bijvoorbeeld niet automatisch converteren naar een variabele met als type Long (Hearn, 2015). Die beperking volgt uit het feit dat Kotlin correctheid prefereert en enkel de wrapperklassen van de primitieve datatypes kent. Bij een automatische conversie van een Integer naar een Long zou een gelijkheidscontrole tussen het origineel en de conversie naar ‘onwaar’ evalueren omdat beide een verschillend referentiedatatype hebben. De automatische conversie zou met andere woorden de gelijkheid tussen beide variabelen verstoren. Wil men de conversie toch uitvoeren, dan kan dat enkel impliciet met behulp van een conversiemethode zoals toLong (“Basic Types”, s.d.). 66 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 7.Toekomst van Kotlin 67 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Als programmeertaal staat Kotlin op dit moment nog in haar kinderschoenen. Het project werd opgestart in de loop van 2010, en pas in februari 2016 werd een eerste officiële productieversie geïntroduceerd. JetBrains gaat er echter van uit dat Kotlin 1.0 reeds voldoende volwassen is om gebruikt te worden in reële productieomgevingen. Om die stelling te staven, zet het bedrijf de taal dan ook in voor zijn eigen projecten (Breslav, 2016). In de nabije toekomst wil JetBrains zich vooral concentreren op het verhogen van de performantie van Kotlin-gereedschappen zoals de compiler en de IDE-plug-in. Verder wordt er ook gewerkt aan incrementele compilatie voor Gradle-projecten, waardoor bij iedere build niet steeds de volledige code, maar enkel de nieuwe toevoegingen moeten worden gecompileerd. Dat betekent een enorme tijdswinst voor ontwikkelaars, en in het bijzonder voor Android-programmeurs, aangezien Googles besturingssysteem gebruikmaakt van Gradle als buildsysteem. Ten slotte wil het Kotlin-team ook werk maken van de JavaScript-compiler en de ondersteuning voor Java 8 bytecode. Dat laatste werkpunt zou betekenen dat de Kotlin-compiler ook kan compileren naar die recentere en meer efficiënte bytecode in plaats van de tot op heden gebruikte Java 6 bytecode (Breslav, 2016). De eventuele overstap naar Java 8 bytecode zou volgens JetBrains niet mogen betekenen dat Android- ontwikkelaars, die door Google nog steeds aangewezen zijn op Java 6 of 7, zomaar in de steek gelaten worden. Het bedrijf gaat er prat op dat het zolang als nodig voor Android een optie zal bieden om naar Java 6 bytecode te compileren. Verder wordt ook langdurige achterwaartse compatibiliteit gegarandeerd, waardoor nieuwere versies van de taal en haar gereedschappen compatibel zullen blijven met oudere syntax (Breslav, 2016). 68 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 8.Praktijkvoorbeeld 69 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Voor dit hoofdstuk wordt een eenvoudige applicatie gemaakt in Kotlin en standaard-Android. De Kotlintoepassing maakt voor haar lay-out ook gebruik van de Anko-bibliotheek, terwijl de basistoepassing het houdt bij standaard-XML. Zonder de code van de projecten nader te vergelijken, wordt er technisch bekeken welk van beiden het meest efficiënt is. Criteria die daarbij in acht genomen worden, zijn: het aantal lijnen code (lay-out en logica), het totale aantal methodes, de grootte van het gepubliceerde APKbestand en de tijd die nodig is om het project te builden in de verschillende fases van de ontwikkeling. De applicatie betreft een eenvoudige toepassing waarbij JSON-gegevens over de Brusselse stripfigurenmuren worden opgehaald van een open datanetwerk. In een eerste fragment wordt de lijst met stripfigurenmuren getoond, in een tweede fragment wordt voor elke muur de locatie getoond op een kaart van Google Maps. Figuur 12: Screenshots van de Android- en Kotlin-praktijkapplicaties. 8.1. Buildtijden Om de duurtijd van het builden bij beide applicaties te vergelijken, werden in de projecten vier milestones gedefinieerd. Elke milestone komt overeen met een afgewerkt deel van de applicatie: 70 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? • Onder de eerste milestone wordt het aanmaken van de projecten verstaan. In het geval van de Android-applicatie, betekent dat dat de eerste en enige Activity is aangemaakt in code en XML. Geen van beide bestanden bevat reeds een implementatie. Hetzelfde geldt voor het Kotlin-project, alleen werden daar de benodigde afhankelijkheden voor Kotlin en Anko reeds toegevoegd aan het Gradle-bestand op moduleniveau. • De tweede milestone omvat voor beide projecten een eerste afgewerkt fragment. De lijst met stripfigurenmuren wordt reeds getoond en de achterliggende Adapter en ViewHolder zijn reeds aangemaakt. De foto’s van de bekende muren worden nog niet getoond. • De derde milestone voegt de afbeeldingen toe aan de lijst met stripfigurenmuren. • De vierde milestone betekent het aanmaken van het tweede fragment en de daarbijhorende initialisatie van de Google Maps-kaarten. Na de afwerking van een milestone werd voor elk van beide projecten tien keer een build uitgevoerd. De duurtijden werden daarop genoteerd en onderstaande tabel toont per milestone de gemiddeldes in milliseconden. Tegelijkertijd wordt ook het procentuele verschil tussen de Android-applicatie, die hier als richtlijn genomen is, en de Kotlin-toepassing weergegeven. Milestone Android Kotlin Verschil Milestone1 3520 ms 4581 ms 23,2% Milestone2 3565 ms 5461 ms 34,7% Milestone3 3696 ms 5889 ms 37,2% Milestone4 4224 ms 6581 ms 35,8% Figuur 13: Vergelijking van buildtijden in Android en Kotlin bij de vooraf gedefinieerde milestones. Bovenstaand overzicht leert dat het builden van een gelijke Kotlin-applicatie steeds 23,2% tot 37,2% extra tijd vraagt. Het gemiddelde extra duurpercentage bedraagt over de hele applicatie 32,7%. In een kleine toepassing, zoals deze, betreffen de verschillen maximaal twee seconden, maar in grote applicaties kunnen ze al snel hoger oplopen. De gewonnen ontwikkelingsproductiviteit wordt dus deels terugbetaald middels een hogere buildtijd. JetBrains beloofde bij de lancering van Kotlin 1.0 wel om bij volgende versies van de programmeertaal de efficiëntie van het compileren en het builden te verhogen (Breslav, 2016). 8.2. Het aantal lijnen code Voor dit onderdeel van de proef worden alle codebestanden, gaande van het manifest tot en met de eigenlijke code en de lay-out, in rekening genomen. Enkel de Gradle-bestanden en externe bibliotheken 71 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? worden genegeerd. Om een duidelijk onderscheid te maken tussen logica en lay-out, wordt er voor de Android-applicatie een differentie gemaakt tussen XML-lay-out en Java-logica. Bij de Kotlin-toepassing wordt dat onderscheid weerspiegeld door het uit elkaar halen van de logica en de Anko-lay-out. In beide gevallen worden overige XML-bestanden, zoals het manifest, de drawables en de strings, ondergebracht in een aparte categorie met de naam ‘overige’. De bijgevoegde tabel toont de vergelijking in het aantal lijnen code tussen een Android-applicatie en een gelijke Kotlin-toepassing. Categorie Android Kotlin Lay-out 60 121 Logica 514 431 Overige 59 69 Totaal 633 621 Figuur 14: Vergelijking van het aantal lijnen code in Android en Kotlin. In het uiteindelijke resultaat ontlopen beide voorbeeldapplicaties elkaar nauwelijks. Kotlin bewijst zijn diensten in het compacter schrijven van de eigenlijke logica, maar de XML-weergave van de lay-out blijkt wel nog steeds korter dan de Anko-benadering. Een combinatie van Kotlin voor de logica en XML voor de lay-out blijkt in de praktijk dan ook het meest te lonen. De Kotlin Android Extensions kunnen bij die combinatie helpen. 8.3. De grootte van het APK-bestand Voor beide applicaties werd een APK-bestand gegenereerd. In geen van beide gevallen werd er gebruikgemaakt van minification en obfuscation. De bijhorende tabel toont de grootte van het APKbestand voor de applicaties in bytes. Android Kotlin 2.249.948 bytes 2.743.044 bytes Figuur 15: Vergelijking van de grootte van het APK-bestand in Android en Kotlin. Het toevoegen van de Kotlin- en Anko-bibliotheken betekent dat het APK-bestand een halve megabyte groter is dan dat van de Android-toepassing. 72 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 8.4. Het aantal methodes Het aantal methodes van beide applicaties werd gemeten met behulp van het Dex Method Countsscript van Mihai Parparita (2015). Het aantal methodes dat een applicatie telt, is vooral belangrijk met betrekking tot de DEX-limiet. Die ligt op 65.563 methodes. Wordt die limiet overschreden, dan moet met MultiDexing gewerkt worden, wat vooral op toestellen met een besturingssysteem van voor Android 5.0 voor problemen kan zorgen. De hieronder beschreven tabel toont een vergelijking in het aantal methodes tussen de Android-applicatie enerzijds en de Kotlin-toepassing anderzijds. API Android Kotlin com.kristofcolpaert.androidapplication 59 126 kotlin 0 6.584 anko 0 2.234 overige 26.035 26.550 Totaal 26.094 35.494 Figuur 16: Vergelijking van het aantal methodes in Android en Kotlin. De resultaten tonen aan dat Kotlin en Anko een aanzienlijk aantal extra methodes toevoegen bovenop het Android-framework. In totaal gaat het om 8.818 functies. Bovendien blijkt Kotlin, ondanks zijn beknoptere syntax, in de achtergrond meer methodes te genereren. Een groot deel daarvan (22), kan geschreven worden op conto van de programmatorisch beschreven lay-out via Anko. Dat gegeven neemt evenwel niet weg dat Kotlin een grotere druk uitoefent op het aantal methodes dan standaardAndroid. Wordt dezelfde functionaliteit geïmplementeerd via externe bibliotheken, dan is Kotlin opnieuw in het voordeel. Zo berekende Jake Wharton (2015c) dat lambda-expressies via de Retrolambda-library een stuk meer methodes verbruiken dan dezelfde expressies in Kotlin. 73 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? 9.Conclusie 74 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Zoals Jake Wharton en Michael Pardo het in hun respectievelijke presentaties reeds aangaven, is het Android-framework in zijn huidige hoedanigheid weinig aantrekkelijk voor ontwikkelaars. Waar concurrerende systemen als Apple Swift en Microsoft .NET meegaan met hun tijd en zich ontpoppen tot programmeeromgevingen met moderne en functioneel gerichte gereedschappen, blijft Android hangen bij een platform dat achterloopt op zijn tijdsgeest. Kotlin springt in die opening en wordt daarom niet helemaal onterecht het “Swift voor Android” genoemd. De taal maakt het programmeren van toepassingen beknopter, expressiever en eenvoudiger. Op die manier biedt ze een uitweg voor de hindernissen die heel wat Android-ontwikkelaars op hun creatieve pad naar een applicatie tegenkomen. Het maakt hen bovendien ook een stuk productiever. Er moeten evenwel ook een aantal kanttekeningen gemaakt worden bij dat rooskleurige verhaal. Zo staat Kotlin bijvoorbeeld nog in zijn kinderschoenen, zijn er extra kosten met betrekking tot de hardware en is de toekomst van de taal net iets minder zeker dan die van Java in Android. Wegen die nadelen zwaarder dan de eerdergenoemde voordelen van de taal? Niet noodzakelijk. Zoals het voorafgaande onderzoek uitwees, heeft Kotlin wel degelijk een meerwaarde voor Androidprogrammeurs. Die meerwaarde zal bovendien enkel nog groeien naarmate JetBrains de taal en haar gereedschappen verder verfijnt. Dat gegeven neemt evenwel niet weg dat de keuze voor Kotlin bovenal individueel, projectafhankelijk en genuanceerd moet zijn. 75 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Referentielijst Amedeo, R. (2016). Android N switches to OpenJDK, Google tells Oracle it is protected by the GPL. Geraadpleegd op 28 januari, 2016 via http://arstechnica.com/tech-policy/2016/01/android-nswitches-to-openjdk-google-tells-oracle-it-is-protected-by-the-gpl Android Developer (2016). Platform versions. Geraadpleegd op 29 januari, 2016 via http://developer. android.com/about/dashboards/index.html#Platform Android Developer (s.d.). Glossary. Geraadpleegd op 30 januari, 2016 via http://developer.android. com/guide/appendix/glossary.html Android Developer (s.d.). Processes and Threads. Geraadpleegd op 13 februari, 2016 via http:// developer.android.com/guide/components/processes-and-threads.html#Threads Android Developer (s.d.). ProGuard. Geraadpleegd op 10 maart, 2016 via http://developer.android. com/intl/es/tools/help/proguard.html Android Developer (s.d.). Build System Overview. Geraadpleegd op 10 maart, 2016 via http://developer. android.com/intl/es/sdk/installing/studio-build.html Android Developer (s.d.). Intents and Intent Filters. Geraadpleegd op 13 maart, 2016 via http://developer. android.com/guide/components/intents-filters.html Android Developer (s.d.). Providing Alternative Resources. Geraadpleegd op 13 maart, 2016 via http:// developer.android.com/guide/topics/resources/providing-resources.html#QualifierRules Android Developer (s.d.). Processes and Threads. Geraadpleegd op 13 maart, 2016 via http://developer. android.com/guide/components/processes-and-threads.html Android Developer (s.d.). App Manifest. Geraadpleegd op 13 maart, 2016 via http://developer.android. com/guide/topics/manifest/manifest-intro.html Beust, C. (2011). Five reasons whe you should rejoice about Kotlin. Geraadpleegd op 20 februari, 2016 via http://beust.com/weblog/2011/07/20/five-reasons-why-should-rejoice-about-kotlin/ Breslav, A. (2016). Kotlin 1.0 Released: Pragmatic Language for JVM and Android. Geraadpleegd op 20 februari, 2016 via http://blog.jetbrains.com/kotlin/2016/02/kotlin-1-0-released-pragmaticlanguage-for-jvm-and-android/ Breslav, A. (2015). Feedback Request: Limitations on Data Classes. Geraadpleegd op 27 februari, 2016 via http://blog.jetbrains.com/kotlin/2015/09/feedback-request-limitations-on-data-classes/ 76 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Burke, D (2016). First Preview of Android N: Developer APIs & Tools. Geraadpleegd op 9 maart, 2016 via http://android-developers.blogspot.be/2016/03/first-preview-of-android-n-developer.html Clarke, G. (2016). Was Android moving to OpenJDK really a Google gift to devs? Geraadpleegd op 28 januari, 2016 via http://www.theregister.co.uk/2016/01/08/android_on_openjdk_good_for_devs_ bad_for_business De Jong, J. (2012). What is meant by a primitive data type? Geraadpleegd op 8 februari, 2016 via http:// programmers.stackexchange.com/a/139755 De Simone, S. (2016). Q&A with Andrey Breslav on the Kotlin 1.0 Release. Geraadpleegd op 20 februari, 2016 via http://www.infoq.com/news/2016/02/kotlin-10-released Dischler, J. (2015). Building for the next moment. Geraadpleegd op 28 januari, 2016 via http://adwords. blogspot.co.uk/2015/05/building-for-next-moment.html Eckel, B. (s.d.). Does Java need Checked Exceptions? Geraadpleegd op 7 februari, 2016 via http:// www.mindview.net/Etc/Discussions/CheckedExceptions Frankel, N. (2013). A dive into the Builder pattern. Geraadpleegd op 12 februari, 2016 via https://blog. frankel.ch/a-dive-into-the-builder-pattern GitHub - Kotlin (s.d.). Anko. Geraadpleegd op 10 februari, 2016 via https://github.com/Kotlin/anko/blob/ master/README.md Github – Kotlin (s.d.). Anko Advanced topics. Geraadpleegd op 12 februari, 2016 via https://github.com/ Kotlin/anko/blob/master/doc/ADVANCED.md Github – Kotlin (s.d.). Anko Loves SQLite. Geraadpleegd op 14 februari, 2016 via https://github.com/ Kotlin/anko/blob/master/doc/SQLITE.md Goetz, B. (2014). Lambdas and Streams in Java 8 Libraries. Geraadpleegd op 28 januari, 2016 via http://www.drdobbs.com/KZhLZ/jvm/lambdas-and-streams-in-java-8-libraries/240166818 Gordon, S. A. (2015). What is an APK file and how do you install one? Geraadpleegd op 10 maart, 2016 via https://www.androidpit.com/android-for-beginners-what-is-an-apk-file Hariri, H. (2012). The Kotlin Journey Part IV: Adding functionality. Geraadpleegd op 10 februari, 2016 via http://hadihariri.com/2012/09/27/the-kotlin-journey-part-iv-adding-functionality/ Hearn, M. (2015). Why Kotlin is my next programming language. Geraadpleegd op 31 januari, 2016 via https://medium.com/@octskyward/why-kotlin-is-my-next-programming-languagec25c001e26e3#.684j7b13k 77 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Jemerov, D. & Isakova, S. (2015). Kotlin in action. New York: Manning. Jemerov, D. (2013). IntelliJ and Android Studio FAQ. Geraadpleegd op 14 februari, 2016 via http://blog. jetbrains.com/idea/2013/05/intellij-idea-and-android-studio-faq/ Jenkins, K. (2015). What is Functional Programming? Geraadpleegd op 2 februari, 2016 via http://blog. jenkster.com/2015/12/what-is-functional-programming.html Käppler, M. (2015). “Congratulations, you have a lot of code!” Remedying Android’s method limit – Part 1. Geraadpleegd op 30 januari, 2016 via https://developers.soundcloud.com/blog/congratulationsyou-have-a-lot-of-code-remedying-androids-method-limit-part-1 Kotlinlang (s.d.). Kotlin programming language. Geraadpleegd op 31 januari, 2016 via https://kotlinlang. org Krill, P. (2011). JetBrains readies JVM-based language. Geraadpleegd op 31 januari, 2016 via http:// www.infoworld.com/article/2622405/java/jetbrains-readies-jvm-based-language.html Kotlin (s.d.). Data Classes. Geraadpleegd op 3 februari, 2016 via https://kotlinlang.org/docs/reference/ data-classes.html Kotlin (s.d.). Type Checks and Casts. Geraadpleegd op 3 februari, 2016 via https://kotlinlang.org/docs/ reference/typecasts.html Kotlin (s.d.). Functions. Geraadpleegd op 3 februari, 2016 via https://kotlinlang.org/docs/reference/ functions.html Kotlin (s.d.). Extensions. Geraadpleegd op 3 februari, 2016 via https://kotlinlang.org/docs/reference/ extensions.html Kotlin (s.d.). Classes. Geraadpleegd op 5 februari, 2016 via https://kotlinlang.org/docs/reference/ classes.html Kotlin (s.d.). Interfaces. Geraadpleegd op 5 februari, 2016 via https://kotlinlang.org/docs/reference/ interfaces.html Kotlin (s.d.). Calling Java code from Kotlin. Geraadpleegd op 2 februari, 2016 via https://kotlinlang.org/ docs/reference/java-interop.html Kotlin (s.d.). Any. Geraadpleegd op 8 februari, 2016 via https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/any/ Kotlin (s.d.). Unit. Geraadpleegd op 8 februari, 2016 via https://kotlinlang.org/api/latest/jvm/stdlib/ kotlin/-unit/ 78 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Kotlin (s.d.). Visibility Modifiers. Geraadpleegd op 10 februari, 2016 via https://kotlinlang.org/docs/ reference/visibility-modifiers.html Kotlin (s.d.). Type-Safe Builders. Geraadpleegd op 12 februari, 2016 via https://kotlinlang.org/docs/ reference/type-safe-builders.html Kotlin (s.d.). Basic Types. Geraadpleegd op 27 februari, 2016 via https://kotlinlang.org/docs/reference/ basic-types.html Lengstof, J. (2009). JSON: What It Is, How It Works, & How to Use It. Geraadpleegd op 13 maart, 2016 via http://www.copterlabs.com/json-what-it-is-how-it-works-how-to-use-it/ Leiva, A. (2015). Kotlin for Android Developers. Victoria (Ca): LeanPub. Leiva, A. (2015). Kotlin for Android Developers. Geraadpleegd op 15 februari, 2016 via http://www. javaadvent.com/2015/12/kotlin-android.html Lentzitzky, O. (2015). Solving Android’s 65K Limit (Part 2): The Lollipop Generation. Geraadpleegd op 30 januari, 2016 via http://blog.safedk.com/technology/solving-androids-65k-limit-part-2-thelollipop-generation Medium (2015). A Quick Dive into Kotlin for Android. Geraadpleegd op 21 februari, 2016 via https:// medium.com/@darrellii/a-quick-dive-into-kotlin-for-android-57d77776b781#.8rl3n8ox3 Oracle (s.d.). The Numbers Classes. Geraadpleegd op 8 februari, 2016 via https://docs.oracle.com/ javase/tutorial/java/data/numberclasses.html Oracle (s.d.). Primitive Data Types. Geraadpleegd op 8 februari, 2016 via https://docs.oracle.com/ javase/tutorial/java/nutsandbolts/datatypes.html Oracle (s.d.). Controlling Access to Members of a Class. Geraadpleegd op 10 februari, 2016 via http:// docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html Oracle (s.d.). Chapter 2. The Structure of the Java Virtual Machine. Geraadpleegd op 10 maart, 2016 via http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.4 Oracle (s.d.). What Is an Exception? Geraadpleegd op 13 maart, 2016 via https://docs.oracle.com/ javase/tutorial/essential/exceptions/definition.html Oracle (s.d.). Anonymous Classes. Geraadpleegd op 13 maart, 2016 via https://docs.oracle.com/ javase/tutorial/java/javaOO/anonymousclasses.html Pardo, M. (2015). A New Hope in a Java 6 Wasteland [YouTube]. Geraadpleegd op 28 januari, 2016 via https://realm.io/news/droidcon-michael-pardo-kotlin 79 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Parparita, M. (2015). Dex Method Counts. Geraadpleegd op 30 januari, 2016 via https://github.com/ mihaip/dex-method-counts Protalinski, E. (2015). Google confirms next Android version will use Oracle’s open-source OpenJDK for Java APIs. Geraadpleegd op 29 januari, 2016 via http://venturebeat.com/2015/12/29/googleconfirms-next-android-version-wont-use-oracles-proprietary-java-apis Paulsen, B. (2015). What is object-oriented programming? Geraadpleegd op 13 maart, 2016 via https:// www.quora.com/What-is-object-oriented-programming Ruiz, A. & Bay, J. (2008). An Approach to Internal Domain-Specific Languages in Java. Geraadpleegd op 10 februari, 2016 via http://www.infoq.com/articles/internal-dsls-java Shrestha, B.R. (2015). Kotlin and Anko for your Android! Geraadpleegd op 12 februari, 2016 via https:// medium.com/@BhaskerShrestha/kotlin-and-anko-for-your-android-1c11054dd255#.5uo3vc9cs StackOverflow (s.d.). What is the difference between a Field and a Property in C#? Geraadpleegd op 12 maart, 2016 via http://stackoverflow.com/a/295109 StackOverflow (s.d.). What is parsing? Geraadpleegd op 13 maart, 2016 via http://stackoverflow. com/a/1788808 StackOverflow (s.d.). What is an ORM and where can I leanr more about it? Geraadpleegd op 13 maart, 2016 via http://stackoverflow.com/a/1279678 Urma, R. (2014). Tired of Null Pointer Exceptions? Consider Using Java SE 8’s Optional! Geraadpleegd op 1 februari, 2016 via http://www.oracle.com/technetwork/articles/java/java8-optional-2175753. html Wharton, J. (2015). Advancing Android Development with Kotlin [Vimeo]. Geraadpleegd op 28 januari, 2016 via https://realm.io/news/oredev-jake-wharton-kotlin-advancing-android-dev Wharton, J. (2015). Using Project Kotlin for Android. Geraadpleegd op 29 januari, 2016 via https:// docs.google.com/document/d/1ReS3ep-hjxWA8kZi0YqDbEhCqTt29hG8P44aA9W0DM8/ edit?hl=en&forcehl=1 Wharton, J. (2015). Android Development with Kotlin – Jake Wharton [YouTube]. Geraadpleegd op 4 maart, 2016 via https://youtu.be/A2LukgT2mKc Wikipedia (s.d.). Interoperabiliteit. Geraadpleegd op 2 februari, 2016 via https://nl.wikipedia.org/wiki/ Interoperabiliteit Wikipedia (s.d.). Singleton (ontwerppatroon). Geraadpleegd op 10 februari, 2016 via https://nl.wikipedia. org/wiki/Singleton_(ontwerppatroon) 80 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Wikipedia (s.d.). Open source. Geraadpleegd op 10 maart, 2016 via https://nl.wikipedia.org/wiki/Open_ source Wikipedia (s.d.). Framework. Geraadpleegd op 10 maart, 2016 via https://nl.wikipedia.org/wiki/ Framework Wikipedia (s.d.). Compiler. Geraadpleegd op 10 maart, 2016 via https://nl.wikipedia.org/wiki/Compiler Wikipedia (s.d.). JAR. Geraadpleegd op 10 maart, 2016 via https://nl.wikipedia.org/wiki/JAR Wikipedia (s.d.). Functioneel programmeren. Geraadpleegd op 10 maart, 2016 via https://nl.wikipedia. org/wiki/Functioneel_programmeren Wikipedia (s.d.). Function overloading. Geraadpleegd op 11 maart, 2016 via https://en.wikipedia.org/ wiki/Function_overloading Wikipedia (s.d.). Event (computing). Geraadpleegd op 13 maart, 2016 via https://en.wikipedia.org/wiki/ Event_(computing) Wikipedia (s.d.). Software development kit. Geraadpleegd op 13 maart, 2016 via https://nl.wikipedia. org/wiki/Software_development_kit Wikipedia (s.d.). Application programming interface. Geraadpleegd op 13 maart, 2016 via https:// nl.wikipedia.org/wiki/Application_programming_interface Zhulanow, Y. (2015). Kotlin Android Extensions. Geraadpleegd op 10 februari, 2016 via https://kotlinlang. org/docs/tutorials/android-plugin.html 81 Bachelorproef Kristof Colpaert Welke meerwaarde biedt Kotlin aan de ontwikkelaar bij het maken van Android-applicaties? Bijlagen Resultaten praktijktests Kotlin Resultaten praktijktests Android 82