Apps ma­ken met Dart en Goog­le Flut­ter

An­droid- en iOS-apps ont­wik­ke­len met Dart en Goog­le Flut­ter

C’t Magazine - - Inhoud 9/2018 - Tam Han­na, Jörg Wirt­gen

Met Goog­les oor­spron­ke­lijk al­leen in­tern ge­bruik­te fra­me­work Flut­ter kun je An­droid- en iOS-apps ont­wik­ke­len op ba­sis van de­zelf­de co­de. Aan­pas­sin­gen be­lan­den daar­mee heel snel op test­ap­pa­ra­ten en emu­la­tors. Maar om zich te on­der­schei­den van Re­ac­tNa­ti­ve, Pho­neGap, Xa­ma­rin en Qt moet Flut­ter meer bie­den.

Zo­als ge­brui­ke­lijk bij een pol­der­mo­del­com­pro­mis zijn er al­tijd wel par­tij­en on­te­vre­den. Het lijkt als­of Goog­le dat bij de pro­gram­meer­taal van Flut­ter als uit­gangs­punt had. De An­droid­ta­len Ja­va en Kot­lin wor­den niet ge­bruikt, net zo min als de iOS-ta­len Swift en Ob­jec­ti­ve C. De keu­ze is ook niet ge­val­len op de ge­meen­schap­pe­lij­ke noe­mer C++. Het bij con­cur­ren­ten als Re­ac­tNa­ti­ve en Pho­neGap in­ge­zet­te Ja­vaScript is het ook niet ge­wor­den. In plaats daar­van wordt Dart ge­bruikt, een door Goog­le ont­wik­kel­de taal die en­ke­le na­de­len van Ja­vaScript weg moet ne­men.

Dart is in elk ge­val een mo­der­ne taal die pro­gram­meurs veel werk be­spaart, ook al werkt het soms wat om­slach­ti­ger dan Kot­lin. Dart 2 (in de laat­ste bè­ta­ver­sie van Flut­ter) is al wat com­pac­ter. Ont­wik­ke­laars zul­len met Dart net zo min gro­te pro­ble­men heb­ben als met de struc­tuur van Flut­ter. Als ont­wik­kelom­ge­ving on­der­steunt Flut­ter An­droid Stu­dio, In­tel­liJ en Vi­su­al Stu­dio, maar het is ook te kop­pe­len aan an­de­re edi­tors. Om iOS-apps te ma­ken is een Mac no­dig.

Voor Dart be­staan zo­wel com­pi­lers als snel­le vir­tu­e­le ma­chi­nes. Daar­door kan Flut­ter een twee­le­di­ge ar­chi­tec­tuur ge­brui­ken: voor een be­te­re per­for­man­ce kun­nen vol­tooi­de apps op het ont­wik­kel­sys­teem ge­com­pi­leerd wor­den en van een klei­ne run­ti­me voor­zien wor­den. Maar tij­dens het ont­wik­ke­len draait op het test­ap­pa­raat een de­bug-run­ti­me met een vir­tu­e­le Dart­ma­chi­ne. Die krijgt bij aan­pas­sin­gen in de co­de geen com­pleet nieu­we app, maar al­leen de ge­wij­zig­de co­de. De vir­tu­e­le ma­chi­ne sluist die door naar de JIT-com­pi­ler en voert de app zon­der on­der­bre­kin­gen uit.

Geen tijd­ver­lies

De in­houd van pri­va­te mem­bers van ge­wij­zig­de klas­sen blijft daar­bij be­hou­den, zo­dat je de co­de van een draai­en­de app daad­wer­ke­lijk kunt aan­pas­sen zon­der dat bij­voor­beeld in­ge­vul­de in­houd in for­mu­lie­ren ver­lo­ren gaat. Een ver­van­ging gaat blik­sem­snel, voor­dat je na het op­slaan in de IDE je blik op het test­ap­pa­raat ge­richt hebt, draait de emu­la­tor draait de nieu­we co­de daar al. Bij gro­te­re aan­pas­sin­gen, bij­voor­beeld als de klas­sen­struc­tuur of de mem­bers van een klas­se wor­den aan­ge­past, loopt dit me­cha­nis­me te­gen zijn gren­zen aan. Dat geldt bij­voor­beeld ook bij een ge­wij­zig­de

fi­nal-de­cla­ra­tie. De IDE her­kent veel van dit soort ge­val­len en sug­ge­reert dan een vol­le­di­ge her­start. Zelfs dat gaat in­clu­sief voor­be­rei­den­de han­de­lin­gen in de IDE veel snel­ler dan met Ja­va/Kot­lin gang­baar is. Al­leen de eer­ste keer star­ten van een app duurt meest­al lang. De bè­ta­ver­sie die we ge­bruik­ten start­te soms wel een ou­de­re app-ver­sie, zo­dat we flut­ter clear in het ter­mi­nal­ven­ster moesten in­voe­ren of de build-di­rec­to­ry moesten leeg­ma­ken. Die bug is ho­pe­lijk snel ver­hol­pen.

Zon­der GUI-buil­der

De snel­le turn-around-tij­den zijn goed be­ke­ken ook wel no­dig: Flut­ter biedt

geen gra­fi­sche GUI-edi­tor of op­maak­taal. De ont­wik­ke­laar ont­werpt de ge­brui­kers­in­ter­fa­ce uit­slui­tend in de nor­ma­le Flut­ter­co­de. Daar­bij wor­den zo­wel de be­die­nings­ele­men­ten als lay-out­voor­schrif­ten in een wid­get­struc­tuur op­ge­bouwd, die wor­den op­ge­no­men in een han­di­ge con­struc­tor­cas­ca­de:

Wid­get build(BuildCon­text con­text) { re­turn new Ma­te­ri­alApp( tit­le: 'Flut­ter-Test', ho­me: new Scaf­fold( ap­pBar: new Ap­pBar(

tit­le: new Text('Flut­ter Test')), bo­dy: new Cen­ter( child: new Text('Hel­lo ${Plat­form.ope­ra­tingSy­s­tem}')) ));}

In een con­struc­tor kun je ook lis­te­ners on­der­bren­gen en daar­mee bij­voor­beeld knop­pen met­een van func­ties voor­zien. Bij het ty­pen kun je de fat-ar­row-no­ta­tie ge­brui­ken om al­le een­re­ge­li­ge func­ties van de vorm van {re­turn x;} af te kor­ten tot => x;. Ver­der mo­gen in Dart 2.0 de sleu­tel­woor­den new en const weg­ge­la­ten wor­den.

Bo­ven­dien is het mo­ge­lijk om door be­paal­de con­di­ties te la­ten be­pa­len wel­ke wid­gets een app weer­geeft. Zo kun je een app on­der An­droid en iOS ver­schil­len­de wid­gets la­ten ge­brui­ken via het aan­roe­pen van dart:io van Plat­fom.isAn­droid() of .isIOS(). Of je kunt met Me­diaQu­ery. of(con­text).orien­ta­ti­on kie­zen tus­sen ver­schil­len­de wid­gets voor por­tret- of lig­gen­de stand.

Geen aan­pas­sin­gen

De gra­fi­sche wid­gets wor­den zon­der te­rug te grij­pen op de na­ti­ve ele­men­ten van het be­stu­rings­sys­teem door een ei­gen ren­de­ring-en­gi­ne van Flut­ter ge­te­kend. Daar­door is het van An­droid ge­ko­pi­eer­de Ma­te­ri­al De­sign be­schik­baar on­der iOS en zijn de van iOS ge­ko­pi­eer­de be­die­nings­ele­men­ten bruik­baar on­der An­droid. Het zijn weg­wer­pe­le­men­ten met een on­ver­an­der­lij­ke in­houd, die het fra­me­work steeds ver­wij­derd en op­nieuw maakt in plaats van ze om­slach­tig te ca­chen. Voor 3D-toe­pas­sin­gen is Flut­ter niet ge­schikt.

De ver­an­der­lij­ke da­ta van bij­voor­beeld een in­voer­veld be­vin­den zich in een set van Sta­te-ob­ject en Sta­te­fulWid­get, die bei­de geen recht­streek­se gra­fi­sche re­pre­sen­ta­tie heb­ben. Sta­te re­a­geert op ge­brui­ker­sin­put en cre­ëert bij ge­wij­zig­de da­ta steeds een nieu­we wid­get­cas­ca­de met de ac­tu­e­le in­houd. Een Sta­te kan bo­ven­dien voor een he­le reeks in­voer­vel­den of al­les van een for­mu­lier ver­ant­woor­de­lijk zijn, wat een kop­pe­ling ver­een­vou­digt. Toch is er ver­ge­le­ken met het be­perkt aan­tal be­no­dig­de re­gels in An­droid of iOS in elk ge­val in het be­gin wat ver­lies merk­baar qua ef­fi­ci­ën­tie.

Zon­der Dart

Via een pack­a­ge-sys­teem kun­nen af­ge­ron­de mo­du­les wor­den ge­ïn­te­greerd of kun je zelf mak­ke­lijk nieu­we mo­du­les cre­ë­ren. Er zijn er al di­ver­se be­schik­baar, maar het bre­de aan­bod aan mo­du­les en plug-ins en­zo­voort dat voor an­de­re sys­te­men be­staat, is er nog niet voor Flut­ter.

De in­te­gra­tie van na­ti­ve Ja­va, Kot­lin, Ob­jec­ti­ve C en Swing co­de is mo­ge­lijk met plat­form-chan­nels. Die im­ple­men­te­ren een een­vou­dig mes­sa­ging-sys­teem van en naar Dart. Je moet daar de iOS- en An­droid-stubs voor uit­brei­den die ho­ren bij elk Flut­ter-pro­ject en de co­de daar­in on­der­bren­gen. Der­ge­lij­ke op­los­sin­gen kun­nen ook als pack­a­ge wor­den ver­pakt en ge­dis­tri­bu­eerd.

De in­te­gra­tie van na­ti­ve gra­fi­sche ele­men­ten is op die ma­nier ech­ter niet mo­ge­lijk. Ook in ei­gen co­de in C/C++ is niet voor­zien, ook al is de Flut­ter-co­re ge­ïm­ple­men­teerd in C++. Het is wel­licht mo­ge­lijk dat te re­a­li­se­ren via de plat­form-chan­nels, als je in­ten­sief aan de slag gaat met Grad­le en de NDK. Die dub­be­le in­kap­se­ling kan ech­ter ten kos­te gaan van de per­for­man­ce. An­ders­om kun je Flut­ter-views in­te­gre­ren in be­staan­de An­droid- en iOS-apps.

Niet on­af­han­ke­lijk

Voor iOS en An­droid is Flut­ter een bij­zon­der cross­plat­form-fra­me­work: gra­tis en ef­fi­ci­ënt door de co­de en in­ter­fa­ce in een ge­meen­schap­pe­lij­ke taal te schrij­ven en blik­sem­snel bij het tes­ten. Te­ge­lij­ker­tijd is het ook merk­baar een bè­ta­ver­sie, be­perkt tot het niet zo po­pu­lai­re Dart, (in ie­der ge­val voor­als­nog) zon­der C/C++ en ver­moe­de­lijk ook in de toe­komst zon­der na­ti­ve wid­gets.

Flut­ter on­der­steunt geen an­de­re plat­forms, web-apps wor­den zelfs ex­pli­ciet uit­ge­slo­ten. Op Goog­les I/O de­vel­o­pers­con­fe­ren­tie was veel aan­dacht voor Flut­ter en werd bij­voor­beeld een be­te­re in­te­gra­tie met Vi­su­al Stu­dio ge­toond en een wid­ge­tin­spec­tor voor ef­fi­ci­ën­ter ont­wik­ke­len. Voor an­de­re plat­forms als Chro­me OS en Li­nux was er ech­ter geen nieuws.

De open­heid zal me­de be­pa­len wat het suc­ces van Flut­ter wordt. Kie­zen voor dit fra­me­work be­te­kent toch een nau­we re­la­tie met Goog­le, ter­wijl je met een cross­plat­form-tool juist on­af­han­ke­lijk wilt wor­den van pro­du­cen­ten van be­stu­rings­sys­te­men (zie ook het ar­ti­kel in de vo­ri­ge c't over cross­plat­form IDE's [1]).

Flut­ter komt niet van de An­droid-tak van Goog­le, maar van de re­cla­me­af­de­ling die zijn dien­sten sys­teem­on­af­han­ke­lijk wil ver­mark­ten. Maar als Flut­ter voor­al in het Goog­le-uni­ver­sum van An­droid, Fuch­sia en mis­schien Chro­me OS blijft han­gen, met daar­bij dan nog iOS, is er niet veel kans dat het toe­kom­sti­ge be­stu­rings­sys­te­men on­der­steunt die niet uit de stal van Goog­le ko­men. Dan helpt het waar­schijn­lijk ook wei­nig dat zo­wel Flut­ter als Dart opens­our­ce zijn. (mdt)

li­te­ra­tuur

[1] Tam Han­na, Eén IDE voor al­len, Apps voor An­droid en iOS te­ge­lijk ont­wik­ke­len, c't 7-8/2018, p.106

De mees­te Flut­ter­wid­gets zijn ge­ba­seerd op Goog­les Ma­te­ri­al De­sign voor An­droid. Maar er zijn er ook in 'Cu­per­ti­no'stijl – en lay-outs zijn ook wid­gets.

An­droid- en iOS-apps uit een en­ke­le sour­ce, dat kan Flut­ter goed.De apps ge­brui­ken ech­ter niet de na­ti­ve gra­fi­sche ele­men­tenvan de plat­forms.

Newspapers in Dutch

Newspapers from Netherlands

© PressReader. All rights reserved.