131

Intro to Android

Embed Size (px)

DESCRIPTION

Architectural concepts for modern android development

Citation preview

  • 1. Introduction2. Android

    i. Historyii. WorldPhoneiii. Ecosystemiv. DesignConsiderationsv. EmergingUseCases

    3. TDDwithRobolectrici. LabBackgroundii. Lab:RobolectricIntegrationiii. Lab:FirstTestiv. WhatToTestv. BestPracticesvi. Lab:UtilityFunctionsvii. OtherTesting

    4. Architecturei. Androidii. ModelViewControlleriii. BuildingBlocksiv. MessagePassingv. ThreadingModel

    5. Fundamentalsi. Activitiesii. Manifestiii. LayoutsandViewsiv. ViewGroupsv. Fragmentsvi. Lab:DesignChunking

    i. Handout:DesignChunkingii. Solution:DesignChunking

    vii. Lab:ConstructTheViewi. Lab:AddDisplayFragmentii. Lab:AddButtonFragmentiii. Lab:DisplayViewiv. Lab:AddButtons

    viii. Applicationix. Lab:AddApplicationx. Lab:EventBus

    6. ResourceSystemi. DesignPrinciplesii. Styles&Themesiii. Dimensions&Colorsiv. Lab:ViewStylesv. Qualifiersvi. Lab:FlexibleDimensionsvii. Lab:Internationalizationviii. Drawablesix. Lab:ButtonStatex. Lab:AppIcon

    7. ManagingtheLifecyclei. ApplicationLifecycleii. ActivityLifecycle

    TableofContents

  • iii. FragmentLifecycleiv. Lab:VisualizingtheLifecyclev. Backstackvi. FragmentManagervii. Lab:AddCalculatorFragmentviii. InstanceState

    8. Lab:Calculatori. Lab:Requirements&Designii. Lab:UserInteractioniii. Lab:GettingOnTheBusiv. Lab:Testingv. Lab:RoutingEventsvi. Lab:MakeItWorkvii. Lab:DeviceRotation

    9. Appendixi. Toolsii. Maveniii. Resourcesiv. IntelliJCommands

    10. Epilogue11. AboutTheAuthor12. Bibliography

  • ThisworkbookwasoriginallycreatedbyCoreyLeighLatislawastrainingmaterialsforanin-personclass.

    Thisisfreealphaversionofthisbook,Ihopeyouenjoyit!Jointhemailinglisttokeepupwiththeofficialrelease.

    Aportionofthedaywillbededicatedtolecture,butit'simportanttogetyoucodingandexploringassoonaspossible!

    Wewillbeworkingthroughaseriesoflabassignmentsasacomplementtothematerialyouwillbelearning.Ourfirstassignmentwillbecreatingacalculatorapplication.ThiswillcoverseveralfoundationalAndroidtopics.Thesecondassignmentwillbearegionalfoodrecommendationappwherewe'llcovernetworking,datamanagement,andservices.

    We'llbepairprogrammingforthemajorityofthelabsessions.Youarewelcometoswitchuppairsasoftenasyoulike,butworkingsoloisn'tpermitted.Ifwehaveanoddnumberofparticipants,I'llpairwithsomeoneintheclass.

    Therearemanypairingmethodologiesoutthere,butIgenerallyfavorpingponging.Inthismodelsomeonewritesafailingtest(red)andthenyouswitchwho'sinthedriver'sseat.Thenewdevelopermakesthetestpass(green)andrefactors(refactor)asnecessary.Thentheywriteafailingtestandthecyclestartsoveragain.

    Ifyouhaven'tpairprogrammedbefore,Ithinkyou'lllikeit.Itcanbequitefunandit'sagreatwaytolearnfromothers.

    WhatToExpect

    HandsOn

    PairProgramming

  • AccordingtoMeier,"mobile-phoneownershipeasilysurpassescomputerownership[and]2009markedtheyearthatmorepeopleaccessedtheInternetforthefirsttimefromamobilephoneratherthanaPC.Manypeoplebelievethatwithinthenext5yearsmorepeoplewillaccesstheInternetbymobilephoneratherthanusingpersonalcomputers."

    Devices,suchasphonesandtablets,arequiteliterallychangingtheworldonepersonandoneappatatime.Smartphoneshavebecomeanindispensablepartofourlivesintheshorttimetheyhavebeenaround!

    Thepotentialyouhavetocreateausefulappforpeopletheworldoverisarareandspecialgift.It'shardtothinkofsomethingmorerewardingtodointhisworldthantomakesuchapersonalconnectionandchangethecourseofpeople'slives.Youcanequippeoplewithknowledge,tools,andgamesthatwillmakethemcompetitiveintheyearstocomeastechnologyadvances.

    It'sanexcitingtimetobecomeandAndroiddeveloper!Thereisahighdemandandlotsofopportunitytomakeanimpactlocallyandglobally.

    KnowingthefoundationsofAndroidwillhelpyouonyourexplorationofthisfascinatingplatformtohelpyoumakeappsthatcanliterallychangetheworld!

    Meier,Reto(2012-04-05).ProfessionalAndroid4ApplicationDevelopment(KindleLocations499-502).JohnWileyandSons.KindleEdition.

    Chapter1:Android

    Resources

  • AbriefhistoryoftheAndroidworld.

    Globalshipmentshavebeenrisingatafastpace.AccordingtotheIDC,lastyearaloneitrose23%.By2018,therewillbeanadditional1.8billiondevicesinpeople'shands.

    Ofthosephones,80.2%willbeAndroid!

    History

  • SmartphoneMomentumStillEvidentwithShipmentsExpectedtoReach1.2Billionin2014andGrowing23.1%Over2013.May28,2014.Retrievedfromhttp://www.idc.com/getdoc.jsp?containerId=prUS24857114.

    References

  • Androidissointriguingbecauseit'sasystemthat'saccessibletotheworldover,notjusttherichestinoursocieties.

    WhatmakesAndroidsoaccessibleisit'sprice.AccordingtoSherman,it'sonaveragelessthanhalfthepriceofaniOSdevice.

    AsofJanuarythisyear,we'vereachedatippingpointwitha$50phone,accordingtoOxford.Thisflingsthedoorswidetodevelopingnationsandopensanewworldofpossibilitiesforapps.Wecancreatemeaningfulexperiencesthatwilltransformtheworld.PhonesarenowhalfthepriceofanOneLaptopPerChildlaptopandarguablymorepowerfultoempowernewpeopletojointheglobalstage.

    AtGoogleI/O,theyunveiledAndroidOne.ThissystemofpartnershipsbetweenOEMsandGooglewillrapidlyaccelerateadoptioninemergingmarketslikelysurpassingcurrentprojections.ThisprojectcoupledwithotherinitiativestobringfasterInternetconnectionstothe"dark"regionsoftheworldwillrapidlyacceleratetechnologyinthoselocations.

    Emergingmarkets,suchasChina,Russia,andIndiaarethefastestgrowingsegment,whichprovidesplentyofnewusecasesandproblemstosolve.

    "Shipmentswillmorethandoublebetweennowand2018withinkeyemergingmarkets,includingIndia,Indonesia,andRussia.Inaddition,Chinawillaccountfornearlyathirdofallsmartphoneshipmentsin2018."

    AccordingtoOxford,"two-thirdsofSouthAfricanswillhaveamobiledatasubscriptionby2017,morethandoubling"thecurrentusage.Also,predictionsestimatethat"mobiledatasubscriptionsinNigeriaandKenyawillrisefromfourpercent"toapproximately25%.

    Howcanyoubestimpactthosemarkets?

    Sherman,J.February18,2014.Retrievedfromhttp://www.digitaltrends.com/mobile/android-way-cheaper-than-ios/.

    WorldPhone

    References

  • Oxford,A.January31,2014.Sub-$50AndroidsmartphonehitsSouthAfricaasMTNlaunchesSteppa.Retrievedfromhttp://www.zdnet.com/sub-50-android-smartphone-hits-south-africa-as-mtn-launches-steppa-7000025828/.Oxford,A.September19,2013.Two-thirdsofSouthAfricanswillbeonlineby2017asmobiledatabooms,Retrievedfromhttp://www.zdnet.com/two-thirds-of-south-africans-will-be-online-by-2017-as-mobile-data-booms-7000020901/.SmartphoneMomentumStillEvidentwithShipmentsExpectedtoReach1.2Billionin2014andGrowing23.1%Over2013.May28,2014.Retrievedfromhttp://www.idc.com/getdoc.jsp?containerId=prUS24857114.

  • Androidhasbeenevolvingforthelastseveralyearsandexpandingitsreachthroughvariousphonesandtablets.AtGoogleI/O2014,theyannouncedthattheyarestandardizingtheAndroidlandscapeacrossphones,tablets,inadditiontowearabletechnologysuchasGlassandWear,TVandevencars!AllofthesedevicesruntheAndroidOSandgiveyoumanyavenuestocreateinnovativenewsystems.

    OneofthelatestadditionstotheunifiedplatformisAndroidinwatchform.

    Thisexcitingnewplatformnotonlyprovidesnotifications(similartothestatusbaronyourphone),butalsoprovidesnewmodesofinteraction.Ifyouhaveanexistingapplicationwithnotifications,youalreadyhaveapresenceonWear.

    Ifyou'reinterestedinWear,checkoutAndroid'swebsite:http://developer.android.com/training/building-wearables.html

    GoogleGlassisanotificationengine,camera,videorecorder,andapplicationhostonyourface.Controversyaside,thereareplentyofinterestingtechnicalaspectstoexplore.

    TherearetwobasicflavorsofGlassapps.FirstyoucanwriteapplicationswiththemirrorAPI,whichdeliverscontenttoyourGlassusingyourownbackend.YoudeliverHTML-basedcardsfordisplay.

    TheotheroptionistowritenativeAndroidapplicationsusingtheGlassDevelopmentKit(GDK).Ifyou'reinterestedindevelopingGlassapps,checkoutthedeveloperwebsite:https://developers.google.com/glass/develop/gdk/

    Google'slatestattemptatputtingAndroidonyourTVwasannouncedatGoogleI/Othisyear.InsteadofrunningaforkofAndroid,astheill-fatedGoogleTVdid,itnowrunsfull,nativeAndroid.Italsohascastingabilitiesbuiltin(integratedChromecast).

    Ifyou'reinterestedindevelopingTVapps,here'smoreinfo:http://developer.android.com/preview/tv/start/index.html

    Weknowrelativelylittleabouttheplatformsinceitwasrecentlyannounced,butit'llworkasaseconddisplayandaninputdevice.YourappswillrunontheintegratedAndroiddeviceinthedashboard(notonthecar).

    DeviceEcosystem

    AndroidWear

    GoogleGlass

    AndroidTV

    AndroidAuto

  • DesigningamobileapplicationisverydifferentfromdesigningforaPC.OnaPC,youcanassumefastprocessors,sizablememory,lotsofstoragespace,andalargedisplay.Usersaregenerallyexpectingtospendalotoftimeinyourapplicationtoaccomplishalargergoal,suchaswritingabookordoingtheirfinances.

    Amobilephoneisaverydifferentdevice!Usersinteractwithitinverydifferentwaysthantheydowithanormalcomputer.Theyareoftenaccomplishingshorttaskswhileonthego.

    AccordingtoMeier,"comparedtodesktopornotebookcomputers,mobiledeviceshaverelatively:

    LowprocessingpowerLimitedRAMLimitedpermanentstoragecapacitySmallscreenswithlowresolutionHighcostsassociatedwithdatatransferIntermittentconnectivity,slowdatatransferrates,andhighlatencyUnreliabledataconnectionsLimitedbatterylife"

    Mobilephonebatteriesarenotoriousforquicklylosingachargeandpeoplegetveryfrustratedwhentheycan'tusetheirphoneforanentireday.Manypeoplecarryaboutbatteryboostersandchargerssothattheywillhaveaccesstotheirphonesafteradayofheavyusage.Youshouldwriteyourapplicationstobeabatteryfriendlyaspossible.

    Thisisevenmoreimportantinthefurtherflungregionsoftheworld,whereKochisharesthat"rechargingyourphoneeverynightisnotanoptionifyouliveinaruralvillagewithoutelectricity.AtoneofUNICEF'sprojectsinruralSenegal,Iencounteredavillageentrepreneurwhostartedabusinesswherehewouldcollecteveryone'scellphonesandforasmallfee,biketoanelectrifiedvillageafewhoursaway,thenbikebackwithphonesatfullcharge."

    Kochifurtherstatesthat,"peopleinthesecountriesspendalotofmoneytokeeptheirphonescharged.Developingaphonewhosebatterylastsforaweek,"andapplicationsthatdon'tneedlesslywastebatterypower,"wouldunlocksmartphonestoalargemarketsegment."

    It'sexpensivetopurchasedata.We'refairlyluckyintheUnitedStatestohaveubiquitousaccesstonetworksonthegoandaffordableplans.That'snotalwaysthecase,eveninotherdevelopednations.

    Tobeabetterdevicecitizen,limittheamountofdatayoudownloadwhileonmobilenetworksandmaximizetheamountyoudownloadanduploadwhenusershaveafasterconnection,suchasWi-Fi.

    Youhavenoideawhatdevicewillberunningyourapplication,especiallysincetheAndroidOSiseverexpandingtonewdevicesandformfactors.Youmustdesignresponsiveappsthatscaletothemultitudeofdevicesonwhichyourapplicationcouldrun.

    DesignConsiderations

    Hardwareconsiderations

    Batteryusage

    Datausage

    Unknownenvironments

  • Anotherthingtokeepinmindisthatyouruser'sattentionspanismuchshorterwhenusingaportabledevice.Usersareusuallyengagedinadifferentactivitywhenusingyourapp,e.g.attendingaparty.ShortburstsofactivitylikesharingapictureonInstagram,sendingatweetaboutthefestivities,orsendingatexttomeetupwiththeirfriendsisthenameofthegame.

    Youalsocan'tassumethatyouhavetheirfullattentionspanforlong.Youwantyourdesignstobebeautifulandintuitivetohelpthemquicklyaccomplishtheirtask.

    Youdon'twantyouruserstobesurprisedbyyourapplication.Youwanttomakesurethatyourdesignsareintuitiveandbehaveinwaysthatareeasytounderstand.Ageneralruleofthumbisifyouneedalengthytutorialtointroduceyourusertotheinterface,it'sprobablytoocomplicated!

    Youalsodon'twantuserssurprisedbyabackgroundactionorlocation-basedactionthattheyhaven'texplicitlysignedupfor.Agreatexampleofwhatnottodoisregularlyannoyingthemwithnotificationsaboutratingyourapplicationorsendingadswhentheyhaven'trequestedthem.

    Kochi,E.May27,2012.Retrievedfromhttp://techcrunch.com/2012/05/27/mobile-developing-world/.Meier,Reto(2012-04-05).ProfessionalAndroid4ApplicationDevelopment(KindleLocations1123-1128).JohnWileyandSons.KindleEdition.

    Attentionspan

    Principleofleastsurprise

    References

  • Inseveralculturestabletsandevenphonesareviewedascommunaldevicesthataresharedforthebenefitofthecommunity.ThatisadifferentmodelthanwetypicallyassumeintheUnitedStates!

    Herearesomeofthemostinterestingemergingusecasesindevelopingnations.

    AccordingtoKochi,"airtimehasbecomeanotherformofcurrency.Imagineyouneedtogetasmallamountofmoneytoyoursisterwholivesinavillagethat'stenhoursdriveaway.Theeasiestwayforyoutodothatistobuysomeairtime,butinsteadoftoppingupyourownprepaidmobileserviceyoutopuphers.Forasmallfee,shecannowgoandcashoutthisairtimewithanagentthatsellsairtime."

    Ogunlesialsosharesthatphonesareableto"abletotransformordinarycitizensdisenchantedbytheirgovernments,intoresistancefighters."Theabilitytosharepicturesandtextinrealtimeisapowerfulwaytofightbrutaland/orcorruptregimes.Ontheflipside,theycanmakecitizenseasiertotrack.

    MobilephonescanspeedreconnectionwithlovedonesinrefugeecampsbyprovidingaSMSorotherregistryfordisplacedpersons(Ogunlesi).Theycouldalsobeusedtocoordinatevolunteereffortsontheground.

    AccordingtoOgunlesi,"byservingasplatformsforsharingweatherinformation,marketprices,andmicro-insuranceschemes,mobilephonesareallowingAfrica'sfarmerstomakebetterdecisions,translatingintohigher-earningpotentials.Farmersareabletosendatextmessagetofindoutcroppricesinplacesthousandsofkilometersaway."

    AccordingtoTsao,inUganda,"lessthan21%ofbirthsofchildrenlessthanfiveyearsoldareregistered."Amobileplatformwasdevelopedsothat"individualscanregisterbirthsanddeaths."

    Also"malaria,adiseaseaffectingnearly3.5billionpeople,hastheopportunitytobethefirstdiseasebeatenentirelybymobile."Thereareseveraleffortsincludingamobileremindersforusingbednets,enabledonations,andincreaseaccesstotestingandtreatment(Tsao).

    "Traffickers,throughtheuseofmobiles,areabletoorganize,advertise,andstreamlinetheirillicitactivitieswhileexpandingtheircriminalnetworks.Asaconsequence,morepeopleareenslavedthanattheheightoftheAtlantictrade,andpartlyduetoanadditiveabilitytocommunicate."MobileprovidesavarietyoftoolsthatcouldmakethisamuchriskierbusinessbyincreasingcommunicationcapabilitiesandphysicaltrackingthroughGPS(Tsao).

    Ogunlesi,T.andBusari,S.September14,2012.Retrievedfromhttp://www.cnn.com/2012/09/13/world/africa/mobile-

    EmergingUseCases

    MobilePayments

    Activism

    DisasterManagement

    Agriculture

    Health

    HumanTrafficking

    References

  • phones-change-africa/.Kochi,E.May27,2012.Retrievedfromhttp://techcrunch.com/2012/05/27/mobile-developing-world/.Tsao,C.October,8,2013.Retrievedfromhttp://www.huffingtonpost.com/clara-tsao/6-ways-mobile-techology-h_b_4054076.html.

  • IcompletelyagreewithMartinFowler:

    Tome,legacycodeissimplycodewithouttests....Codewithouttestsisbadcode.Itdoesn'tmatterhowwellwrittenitis;itdoesn'tmatterhowprettyorobject-orientedorwell-encapsulateditis.Withtests,wecanchangethebehaviorofourcodequicklyandverifiably.Withoutthem,wereallydon'tknowifourcodeisgettingbetterorworse.

    Unittestingisafundamentalaspectofcomputersciencethatisoftenignored.WenevertalkedaboutitincollegeandIdidn'tstarthearingmuchaboutituntilafewyearsintomycodingcareer.

    Iamafairlyrecentconverttounittesting.AtfirstIdidn'tseethevalue.Itfeltlikeextrawork.Afewyearsago,IspentthreemonthsofintensepairingwithanotherAndroiddeveloperanditchangedmywholeoutlook!Seeinghowmuchwewroteeachdayandhowmuchconfidenceweendedupwithinourdesignwasrefreshing.ItwasadeparturefromothergroupsIhadworkedwiththatonlyvaluedquickcode.Thismentalityencouragesgunslinging,cowboycoders.

    Manylanguagesandframeworkshighlyvaluetesting,butit'sanareathatAndroidoverlooked.TherearesometestingcapabilitiesinAndroid,buttheyrelyontheemulatororanattacheddevicesandaretooslowtouseastheprimarymeansoftestingduringthedevelopmentphase.Thistypeoftestingisbettersuitedforfunctionaland/orintegration-basedtestingoffeaturesinyourapplication.

    Whennotusingtesting,thealternativeistobuildtheapplicationandseewhathappens,lookatapptoverifyexpectedbehavior,andreadlogs.It'snotterriblyefficient!

    Unittestingisabestpractice,buthasbeenparticularlydifficultinAndroid.OnelibrarythatmakesthisprocessmuchsimplerisRobolectric.

    Robolectricallowsyoutofocuscloselyontheapplicationyouarebuildingasyoubuildoutpiecebypiece.Youwritejustenoughcodetopassthetests.Itallowsyoutodotargetedandbroadrefactoringwithoutworryingaboutbreakingtherestofthesystem.Ithelpsuswritebettercodeandhelpskeepusontrack.

    RobolectricwascreatedtoruncoreAndroidcomponentsontheJVMandallowdeveloperstoverifyaspectsoftheircodeastheyaredevelopinginsteadofafterthefeaturehasbeendeployedtoanemulatorordevice.

    RunningtestsonanAndroidemulatorordeviceisslow!Building,deploying,andlaunchingtheappoftentakesaminuteormore.That'snowaytodoTDD.Theremustbeabetterway.

    Wouldn'titbenicetorunyourAndroidtestsdirectlyfrominsideyourIDE?Perhapsyou'vetried,andbeenthwartedbythedreadedjava.lang.RuntimeException:Stub!?

    Robolectricisaunittestframeworkthatde-fangstheAndroidSDKjarsoyoucantest-drivethedevelopmentofyourAndroidapp.TestsruninsidetheJVMonyourworkstationinseconds.

    Chapter2:TDDwithRobolectric

    Android

    Robolectric

  • ThislabwillwalkyouthroughusingIntelliJtogeneratetheprojectandmaventomakeintegrateRobolectric.

    AftercreatinganAndroidprojectwiththewizard,youmovethesourcefilesintoamvn-likestructure.ThenyouconfiguremodulesettingsinIntelliJ.ToinstallRobolectric,youwilladdapomfile(mavendependencyfile)intotheproject.Finally,youwillwriteyourfirsttestandrunitinsidetheIDE.

    Integrationcanbetricky,especiallywhencreatingaprojectfromscratch.I'mahugefanoflivinginIDE-landasmuchaspossible,sothisapproachminimizescommandlineworkandmanualprojectconfiguration.

    AversionofthisCalculatorprojectcanbefoundhere:CalculatorLab.

    Ithastagsforallthemajorstepstohelpyouasyouworkthroughthelabs.Ifyouwantedtofollowalongfromthebeginning,startwiththetag2.2-step1.Eachtagmatchesupwiththechapter'ssectionnumbers.

    YouhaveinstalledIntelliJ(CEedition).YouhaveinstalledtheAndroidSDKandconfiguredIntelliJtouseit(tutorialhere).Youhavemaveninstalled.Youhaveinstalledmaven-android-sdk-deployeranddeployedatleastoneSDK,butpreferablyall,toyourlocal~/.m2/repository.

    Adaptedfrom:Latislaw,C.August3,2012.IntegratingRobolectricwithIntelliJ.Retrievedfromhttp://chariotsolutions.com/blog/post/integrating-robolectric-with-intellij/.

    LabBackground

    github

    Prerequisites

    References

  • UsetheIntelliJAndroidwizardtocreateaHelloWorldproject.First,choosethestoragelocationandplatform.

    Onthenextscreen:

    NameyourapplicationCalculatorCreatea"Hello,World!activity"andnameitCalculatorActivitySetthepackagenametocom.mobiquity.calculatorChoose"USBdevice"asthe"TargetDevice"

    RobolectricIntegration

    Step1:CreateAndroidproject

  • UseIntelliJorthecommandlinetomovefilesintothefollowingstructure:

    src/main/java/...src/test/java/...

    Note:IntelliJmightnotlikeitwhenyouaddsubdirectoriestothefoldermarkedassource.Ifyouarehavingtroublesettingupthedirectorystructure,openthescreenshowninthenextstepandremovetheoldsourcefolderbeforeaddingnewsubfolders.

    UpdatemodulesettingsinIntelliJtorecognizethesourceandtestdirectories(below:bluefolderissourceandtestfolderisgreen).

    Step2:Setupdirectoriesformaven

    Step3:ConfigureIntelliJsourceandtestfolders

  • Afteryouaredone,yourprojectshouldlooksomethinglikethis:

    Copythissamplepom.xmlintoliveintherootofyourproject.ChangethegroupIdtosuityourproject(e.g.com.mobiquity.calculator).Ifdesired,alsoedittheartifactId,version,andnamevalues.

    Check"MavenProjects"viewinIntelliJtoensurethatitlookssomethinglikethis:

    Step4:IntegrateRobolectric

    Step5:Maven

  • Ifyouseeerrors,youmayjustneedtorefreshandwaitforittofinishindexing/importingyourlibraries.ItmayhelptorunmvninstallonthecommandlineandrestartIntelliJ.

    Ifyouarestillhavingissues,yourAndroidfacetmaybetheproblem.OpentheAndroidfacetforyourprojectandchangeto"GeneratebyIDE."

    Adaptedfrom:Latislaw,C.August3,2012.IntegratingRobolectricwithIntelliJ.Retrievedfromhttp://chariotsolutions.com/blog/post/integrating-robolectric-with-intellij/.

    References

  • Let'swriteourfirsttest!

    IusetheIDEtogenerateatestinthecorrectfolder.OpenCalculatorActivity.javaandplaceyourcursoronthenameoftheclass.

    UsetheMackeycombinationCommand+Shift+Ttocreatethetestforthisclass.

    Lab:FirstTest

    Step1:Createtestfile

  • WeneedRobolectric'shelptorunourtests.Addthislineabovethetestclassnameandimportassociatedclasses.

    @RunWith(RobolectricTestRunner.class)

    Step2:Testrunner

  • Addafieldfortheactivityundertestsothatwecanaccessitinallofthetestsinthisclass.

    CalculatorActivityactivity;

    ThenusesetUp()topopulateourfield.

    @BeforepublicvoidsetUp()throwsException{activity=Robolectric.buildActivity(CalculatorActivity.class).create().start().resume().get();}

    WeusetheRobolectriclifecyclemanagementfunctionstobuildandstartanactivity.Thelastfunctioncall,get(),returnsatestinstancethatyoucanusetoverifyvariousaspectsoftheactivity'sviewandbehavior.

    Note:Thecallstocreate(),start(),andresume()referencethedifferentphasesofAndroid'sactivitylifecycle.ThiswillbecoveredindetailinChapter6:ManagingtheLifecycle.

    Writeatestfortheactivity.

    @TestpublicvoidshouldNotBeNull()throwsException{assertNotNull(activity);}

    Youcouldruneachtestindividuallyasyouworkwithnewclasses,howeveritshouldbeacommontasktorunalltheunittests(e.g.priortocommit).Icreatearunconfigurationforthewholeproject.Let'screatearunconfigurationthatwillrunallthetestsatonce.

    First,choose"EditConfigurations..."fromthe"Run"dropdownmenu.

    Then,hitthe+buttonandchooseJUnit.

    Step3:Setup

    Step4:Test

    Step5:Createarunconfigforalltests

  • Thenselect,"Allinpackage"andgiveyourconfigurationadescriptivename.

  • Usetherunconfigurationcreatedintheprevioussteptoensureourtestspass.

    Ifyouforgotstep2,you'llseethiserrormessage:

    java.lang.RuntimeException:Stub!atandroid.content.Context.(Context.java:4)atandroid.content.ContextWrapper.(ContextWrapper.java:5)atandroid.view.ContextThemeWrapper.(ContextThemeWrapper.java:5)atandroid.app.Activity.(Activity.java:6)...

    Inthefuture,youcanrightclickonthetestfilenameoramethodnametorunatest,useakeyboardshortcut,orrunthemfromthecommandlinewithmvncleaninstall.

    Ifyouarestillseeingissues,rebuildyourprojectafewtimestoconvinceIntelliJtogeneratetheR.javafile(whichlinkstoallyourapplicationsresources)and/orrunmvninstallfromthecommandline.

    WecanuseIntelliJ'stoolsorthecommandlinetocommitourchangestoagitrepository.Thisstepshowsyoudetailsfor

    Step6:Run

    Step7:IntelliJgitintegration

  • theIDEroute.

    FirstwewanttotellIntelliJthatwewillbeworkinginagitrepository.UsethedropdownmenuVCS->ImportintoVersionControl->CreateGitRepositorytocompletethisstep.

    TODO:Insertimage

    Afterwehaveintegratedgit,let'sviewourcurrentchangeset.UsethedropdownmenuVCS->ShowChangesViewtoseeourcurrentchangeset.

    TODO:Insertimage

    Beforewecommit,weneedtomakesurethatwe'rehappythefileslistedinourchangeset.Thereareseveralfilesweshouldignore,includingIntelliJ'sprojectfileslocatedinthe.idea/folder,the.imlfileforyourproject,andthegen/directory(usedbehindthescenesduringthebuildprocess).Let'suseIntelliJ'stoolstodothiswithintheIDE.

    TODO:Insertimage

    Note:TheIntelliJwizardaddsafewfileswewon'tneedsincewe'renotusingtheantbuildtool.WecansafelydeletethesefilesinsidetheIDEbyrightclickingonthefileandselectingdelete.Thesefilesareant.properties,build.xml,project.properties,local.propertiesandthebin/directory.

    Note:Wealsoremoveproguard-project.txtforthetimebeing.Ifproguardisdesiredforyourproject,youcanconfigureitusingthisfile.

    Oncewe'rehappywiththechangeset,let'scommit.Youshouldalwaysreviewthefilesandchangesyou'reabouttocommitafterpassingallprojecttests.

    TODO:Insertimage

    Nowlet'stalkaboutwhattotest!

    Adaptedandexpanded:Latislaw,C.August3,2012.IntegratingRobolectricwithIntelliJ.Retrievedfromhttp://chariotsolutions.com/blog/post/integrating-robolectric-with-intellij/.

    References

  • Inthissection,we'llcoversomeofthemostcommontypesoftestcasesandbestpracticestoconsiderwhendeterminingyourtestingstrategy.

    Youshouldfocusyourunittestingonbusinesslogic,basicviewvalidation,andfunctionality.Youcanvalidatecertainrequirementsverywellwithunittesting(e.g."whenIclickthisbellimage,itwhistles"or"allactivitieshavealogoonthescreen").

    Herearesomecommonexamples:

    Ensuretheactivityandviewelementsarenotnull.Ensureexpectedfragmentandviewelementsarevisibleonthescreen.Ensurethattheproperresourcesareusedforviewelements.Ensureitemsarehiddenwhenexpected.Ensuretoastsareshown.Ensurethatyourintentstartsthecorrectthing.

    Idon'trecommendinvestingmuchtimeinverifyinglessimportantstylingdetailsandXMLattributes.Youruserinterfaceislikelytochangemanytimesaweek,buttypicallythebasicviewelementsandtheirbehaviorremainthesame.Ifyouupdatedatesteachtimeabuttonhadnewpadding,thatwouldgetverytediousindeed!

    Theapplogois250dphighwithaproportionalwidth,thefilenameismain_logo.png,ithasa20dpleftmarginand12dprightmargin,hasacontentdescriptionof"Text",andiscenteredverticallyoneveryscreen.

    ReturnsstartdiminishingprettyquicklywhenyouverifyeverypossibleXMLattribute!Yourtimeisbestspentonitemsthatarerelevanttobusinessobjectives.Fromthisexample,likelythemostbangforyourbuckwillcomefromtestingthattheproperimageisusedandmakingsurethatitappearsonallexpectedscreens.

    Rememberanyoftheattributesyoudon'ttestcanbecaughtbydesigners,qualityassurance,business,product,and/ortheengineers.Asolidstrategyistosweeptheappneardeploymentwithadesignertomakesuretheappappearsasexpectedonawiderangeofdevices.

    SimpleAnimation

    Latislaw,C.August7,2012.AndroidUnitTestingWithRobolectric.Retrievedfromhttp://chariotsolutions.com/blog/post/android-unit-testing-with-robolectric/.

    TestingConsiderations

    WhatToTest

    WhatNotToTest

    Example

    AdditionalExamples

    References

  • Aswithmostobjectorientedrealms,attempttosimplifythearchitectureasmuchaspossible.Dothisbycreatingabstractorbaseobjectsorinterfaces.Thiswayyoucantestsharedbehaviorinoneplaceinsteadofseveral,whichsimplifiestestsandreducescodeduplication.

    Oftenwewanttoensurethatacertainactionwasperformedbutnotactuallyrunthecode.Todothis,youcreateatestclasswhichextendstheclassundertestandoverride/mockout/trackthataparticularfunctionwascalled.

    Forexample,ifyouwantaparticularclicktomakeanAPIcall,thereisnoneedtomaketheactualcall(sincethiswouldbeanintegrationleveltestanyway).Youcanusethisstrategytotrackthatthefunctionthatinvokesthecallhasbeencalled,butavoidmakingtheactualcall.

    Thisiscanalsobehelpfulwhenanoperationcrashestheunittestingframework(e.g.specialtylibrarythatcausesfunkysideeffects),doesn'tplaynice,orisotherwiseunnecessarytoinvokedirectly.

    Icreateseveralutilityclassestoimprovethereadabilityofmycode.Theseliveinmyteststructureunderthepackagesupport.We'lladdthesefilesinthenextlab.

    Androidstronglyencouragestheuseofabstractingstringresourcesintooneplaceoverusinghard-codedstringconstants.Iliketofollowasimilarpatternanduseatestconstantsclasswhenyouhavelotsoftestdata.ThiscanbereallyhelpfulwhencreatingauserwithlotsoffieldstomockoutaJSONresponse.

    Ifyoufindyourselfwritingsomethingmorethanonce,that'sanexcellenttimetoreassess.LuckilysinceyouwillhavealargebaseofunittestsatyourdisposalaswellaspowerfulIDEtools,therefactoringwillhaveminimalimpactontherestofthesystem!

    Finally,youshouldn'trelysolelyonunitteststoensuretheproperbehaviorofyourapp.Thesetests,thoughquiteuseful,onlygiveyouasmallwindowintoyourappandit'sbehavior.Atminimum,youshouldincludeintegrationleveltestsandhavesomelevelofmanualQAintheprocesstoensureyourappiseverythingthatyouwantittobe.

    Latislaw,C.August7,2012.AndroidUnitTestingWithRobolectric.Retrievedfromhttp://chariotsolutions.com/blog/post/android-unit-testing-with-robolectric/.

    BestPractices

    SimplifyYourArchitecture

    Mock/StubFunctionality

    UtilityFunctions

    CentralizeTestConstants

    Don'tRepeatYourself(DRY)

    RobustTestingStrategy

    References

  • Let'saddutilityfunctionstooursupportpackage.It'llhelpreducethesomeoftheboilerplatewhenweworkthroughlaterlabs.

    TechnicallywithTDDyou'dwaituntiltheexactmomentyouneedthecodetowriteit.Ipreferpracticalityoverbeingpedantic.

    publicclassAssert{publicstaticvoidassertViewIsVisible(Viewview){assertNotNull(view);assertThat(view.getVisibility(),equalTo(View.VISIBLE));}}

    publicclassResourceLocator{publicstaticStringgetString(intstringId){returnRobolectric.application.getString(stringId);}

    publicstaticDrawablegetDrawable(intdrawableId){returnRobolectric.application.getResources().getDrawable(drawableId);}}

    WiththeversionofRobolectricwe'reusing,weneedtomakeourownversionofafragmentstarter.

    Robolectrichasoneforsupportfragments,butdoesn'thaveonefor"normal"platformfragments.Thisshouldbeinanupcomingrelease.We'vecopiedtheirframeworkversionhereandmodifiedtousenormalfragments.YoucanfindthelatestsourceforFragmentTestUtilongithub.

    publicclassFragmentUtil{publicstaticvoidstartFragment(Fragmentfragment){Activityactivity=createActivity();

    FragmentManagerfragmentManager=activity.getFragmentManager();fragmentManager.beginTransaction().add(fragment,null).commit();}

    privatestaticActivitycreateActivity(){returnRobolectric.buildActivity(Activity.class)

    Lab:UtilityFunctions

    CreateAssert.java

    CreateResourceLocator.java

    CreateFragmentUtil.java

  • .create().start().resume().get();}}

  • Therearemanyotherformsoftestingthatyoucanincorporateintoyourdevelopmentlifecycle.Theseothertoolsareoutsidethescopeofthisbook,butarelistedhereforeasyreferenceandfutureexploration.

    HerearetheAndroidsanctionedwaystotest.

    YouuseJunitstyletestsandcreateatestapplicationthatrunswithyournormalapplication.Thetestapplicationexercisestheuserinterface.

    Itcanbegreatforfunctionalorintegrationtesting,butsinceitreliesonanemulator,it'sjusttooslowforas-you-are-building-a-featuretesting.

    http://developer.android.com/tools/testing/testing_android.html

    Thistestingframeworkrunsonthedeviceandusesaccessibilityfeaturestoconductfunctionaltesting.

    http://developer.android.com/tools/help/uiautomator/index.html

    ThisframeworkallowsyoutoscripttestinPythonandrunsyourtestsonanemulator.http://developer.android.com/tools/help/monkeyrunner_concepts.html

    Therearemanytoolsoutthere.Eachapplicationmayleadtoadifferentselection!

    Calabash:http://calaba.sh/Robotium:https://code.google.com/p/robotium/Appium:http://appium.io/

    OtherTesting

    Android

    InstrumentationTesting

    uiautomator

    monkeyrunner

    OtherTools

  • NowthatyouknowwhyAndroidissuchacompellingsystem,let'slookathowthesystemisconstructed.AlotofpainandsufferingcanbesparedifwefollowAndroid'sconventionsandlooselycoupledmodel.Writingcodethiswaymakesiteasiertowriteandmaintain.Weshouldstrivenotonlytomakebeautifulcode,butalsoengagingpersonal,andfastexperiencesforourusers.

    TherearemanylayersofdecouplingintheAndroidsystem.Theapplicationsareindependententitiesthatcansendmessages,butneverknowtoomuchabouteachother.

    Themodelisabstractedawayfromthedisplayofthedataandaccessedbycontentprovidersandothermechanisms.

    ViewsareabstractedfromthebusinesslogicandintoXMLfilesthatmakeiteasytochangetheappearanceoftheviewwithoutchangingthewaythattheviewworks.

    Viewsarealsodecoupledfromtheresourcesthattheyuseandthelogicfromchoosingwhichviewisrightfortheparticulardeviceitisrunningon.

    Assetsandothercontentareabstractedfromtheviewandbusinesslogicsothatthecontentcanchangewithoutrequiringanupdateinthecodetosupportsmallcopychanges.

    Chapter3:Architecture

  • AndroidisanopensourcesoftwareandhardwaresystemthatsitsontopofaLinuxkernel.ItalsoincludesdevicesandthesetofapplicationsthatrunontheOS.

    YoucanbrowsethesourceAndroidOpenSourceProject(AOSP)atsource.android.com.

    Android'sarchitecturehasmanylayers.

    Ifyou'dlikedetailedinformationaboutthestackandAndroid'ssecurityfeatures,youcanreadmorehere:http://source.android.com/devices/tech/security/index.html

    Thetopofthestackiswhereallthebuiltinapplications,3rdpartyapplications,andyourapplicationslive.Allappsherearecreatedequalandhavethesameaccesstotherestofthestack.

    Android

    ArchitectureLayers

  • Thesecondlayerincludestheapplicationframework,whichgivesyouthetoolstowriteapplications,suchastheSDK,activitymanagers,locationmanagers,notificationmanagers,andtheviewsystem.

    ThehardwareaccesslayeriswherelibrariesarelocatedforinteractingwithGPS,Wi-Fi,Bluetooth,NFC,andotherhardwarefeatures.Theruntimeisalsoatthislayer.

    Eachapplicationrunsinit'sownvirtualmachine(VM)instance,whichmeansthatapplicationscannotdirectlyinvadeeachother'sprocessspace.ThesystemprovidesLinux-stylepermissioncontrolswhilemaintaininganopensystemthroughIntentsandotherinterprocesscommunicationcapabilities.

    Atit'slowestlevel,theLinuxkernelhandlesdrivers,powermanagement,andotherlowlevelprocesses.

    ThecompilationphasesincludeturningyourJavafilesinto.dexbytecodefiles,whichisAndroid'sversionofJavabytecode.AnR.javafileiscreatedsothatJavacanrefertotheXMLcomponentsandotherapplicationresources.

    Theoutputofcompilationisan.apk,whichatit'sheartisbasicallya.zipfile.

    Here'smoredetailhereaboutthestagesofcompilation:http://developer.android.com/tools/building/index.html

    DEXbytecodeisrunonavirtualmachine(muchlikeJavarunsontheJVM),calledtheDVM,orDalvikVirtualMachine.TheDVMwaswrittentobeoptimizedformobiledevices.

    Getallthelowleveldetailshere:https://source.android.com/devices/tech/dalvik/index.html

    InthefuturetheDVMwillbereplacedwiththenewAndroidRunTime(ART).

    Yourapplication'sresourcesareboundatruntimewhenAndroiddetermineswhichdeviceitisrunningonandchoosesthebestresourcesforthatparticulardevice.

    Intentsarealsoaruntimebinding.Youissuearequestandanyappthatcanrespondtotherequestwill.Theuserchooseswhichactiontotakebasedonaparticulartypeofrequestorthesystemusesuser'sdefaults.

    Applicationsaresignedwithakey.Thiscombinedwiththeuniquepackagenameiswhatidentifiesanapplicationonthesystem.

    Bydefault,whenyoucreatedevelopmentbuilds,youareusingadefaultkeytosignyourapplication.Youwilluseadifferentkeywithapasswordwhenyouprepareforrelease.

    Note:Onceyoudeployyourapplicationwiththisreleasekeyyouareforeverstuckwiththekeyandpackagename.That'swhyit'ssoimportanttodeterminewhatyou'dliketouseforyourpackagenameandtoalwayskeepyourreleasekeysafe!

    Note:It'spossibletohavebothadebugandreleasesignedversionofthesameapplicationonyourdevicesincethepackagenameandsignatureareusedtogethertoidentifyanapplication.

    Compilation

    Runtime

    Signing

  • Thereareabstractionsateveryleveltohelpyouseparateconcerns,maintaincodeeasier,andsupportthemultitudeofdevicesandformfactorsinthewild.Androidgivesyoutoolstotodecouplethepresentationlayerfromthebusinesslogic.

    AlthoughsomearguethatAndroidisnotatrueMVCsystem,it'shelpfultoapproachitinthisway.

    ModelViewController

  • Theviewandresourcesystemallowsustobreakoutvisualcomponents.Androidautomaticallyhandlesmostofthelogic

    View

  • aboutchoosingwhichcomponenttouseforwhichformfactor.YouspecifythisinXMLandputinspecialfolders.Thisenablesscalingtodifferentformfactorsaswellasinternationalization.

    TheJavalayeriswhereyoutiethevisualcomponentstothebusinesslogicofyourapplicationandwhereyouwouldaccessthemodelordataofyoursystem.Serviceswouldalsofallintothislayer.

    Finally,themodellayeriswhereyouwouldstorethedatathatpowerstheapplication.ContentprovidersallowyoutoabstractSQLqueriesawayfromyourmodel'susersandsurfacedatathroughouttheapplicationandsystemwide,ifyoudesire.

    Controller

    Model

  • Anapplicationismadeupofaseriesofactivityscreens.Thesearestrungtogetherwithintentstostartupthenextactivity.Activitiesarebuildofviewsandfragments.Fragmentsarebuiltfromviews.

    Activitiesarethemajorbuildingblocksofyourapplicationandareroughlythescreensthatyouseeinanapplication.Theyusefragmentsandviewstoconstructtheuserinterfacethatyousee.

    Activitiesarethemajorbuildingblocksofyourapplicationandarethepresentationlayer,orscreensyouseeinanapplication.Activitiesarecomposedofviewsandfragmentsandseveralactivitiesarecombinedtomakeanapplication.

    Fromtheactivityyouhaveaccesstoalltheviews,resources,systemstate,andthemodel.

    Servicesareusedforlongrunningapplications,suchasnetworkoperations.

    Thisisanapplicationwithtextviewsandbuttons.Whenweclickonthebuttonitlaunchesanactivity.

    BuildingBlocks

    Example:

  • We'llgooveralloftheseingreaterdetailinlaterchapters.

  • Intentsallowmessagepassingandlateruntimebindingbetweencomponents.Basicallyyoubroadcastadesire,suchasopeningawebbrowseroraspecificActivityyoucreated.Androidhandlestherest.

    Agoodexampleiswhensharingapictureyousnappedwithasocialnetwork.Youhaveoptions,suchasTwitter,Instagram,etc.dependingonwhatyouhaveinstalled.Ifyouarewritingacameraapplication,youdon'thavetocareabouthowsomeoneplanstosharethepicture,justthattheyareabletodoitinthemannertheywish.

    MessagePassing

    Intents

  • Usingintentsfreesyoutofocusoncreatingthecontentthatisimportanttoyourapplication,notimplementingorforcingpeopletouseaparticularmethod.Itmakesyourappaparticipantinthesysteminsteadofaself-containedappthatmust

  • handleeverythingbyitself.You'repartofthecommunity!

    Youhaveseveraloptionswithwheninvokinganintent:

    Startoneofyourapplication'sowncomponents(e.g.byusingstartActivity()withaninternalclass).Thiskeepstheintentwithinthecurrentprocess'boundaries.Sendanintentforanactivityfromanotherapplicationthatcrossesprocessboundaries.Broadcastasystem-wideintent,suchasopeningawebbrowserorsharingapieceofcontent.Thisalsocrossesprocessboundaries.Thesystempresentstheuserwithanoptionofhowtoreacttotherequest.

    Inthisexample,wearegettingareferencetoabuttonandsettingaclicklistenerthatstartsaninternalactivity.

    findViewById(R.id.activity_button).setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){startActivity(ViewSystemActivity.createIntent(LooselyCoupledActivity.this));}};)

    Eventbusesareagreatwaytodecoupleourcomponentswithoutusingainterfaceorlistenerpatternthatcanproducealotofboilerplatecode.Youcanuseanapplication-widebus,suchasOtto,topassmessages.

    CodeExample

    EventBus

  • Androidisaneventdrivensystem.ThemainUIthreadloopsindefinitelywaitingforaneweventoruserinput.Whensomethingisreceived,itisprocessed.

    Ifadditionalprocessingisrequiredforaparticulareventthatincludesalongrunningoperation,itshouldbedoneinanotherthread.Examplesoflongrunningprocessesarenetworkdownloads,databaselookups,orfileI/O.

    Ifyouattempttodolongrunningprocessingonthemainthread,it'slikelyyouwilleithergetanexceptionoractivitynotrespondingdialog(ANR).Thisshouldbeavoidedatallcostssinceit'sawfuluserexperience!

    Ourfirstapplicationdoesn'tdoanyofthissortofprocessing,sowewilllookatthosetopicsingreaterdetaillater.

    Youcandoallthenormalthreadingthingsyou'reusedtowithJava.YouuseThreadandHandlerclassestopostinformationbacktothemaincallingthread.

    Thesetasksareusedtodobackgroundprocessing,butshouldn'tbeusedforlongrunningtasks.TheyhaveconveniencemethodsthatallowyoutointeractwiththeUIthreadbefore,during,andafteryourprocessiscomplete.ThesetasksaretiedtotheActivity'slifecycle.

    Thisiswhereyouconductlongrunningprocessesthateitherhandlenetworking,streaming,updatingwidgets,oravarietyofothertasks.ServiceslivewithinyourApplication'sprocessboundaries.

    Youcanalsouseafragmentwithoutaviewasabackgroundworker.Whenyouinflatetheview,yousettheviewtonull.ThisistiedtothelifecycleoftheActivity.

    ThreadingModel

    UIThread

    JavaThreads

    AsyncTask

    Service

    BackgroundFragments

  • Inthischapter,we'llgooverthefoundationalbuildingblocksofAndroidandextendourfirstapplication!

    Forthischapter,we'llbereferringthisexampleandstartingourownproject!

    Chapter4:AndroidFundamentals

    Calculator

  • ActivitiesarewritteninJavaandregisteredinthemanifest.Theyliveinthepackagestructurethatyoudefineinthemanifestfile.Youcancreatesubdirectoriestobetterorganizeyourfiles.

    publicclassLooselyCoupledActivityextendsActivity{@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_loosely_coupled);}}

    Whereverpossible,youshouldstrivemakeyouractivitiesasdumbaspossible,essentiallyanemptyshellforyourfragments.You'dalsodoworklikeconfiguringtheactionbarandmenushere.

    IdeallymostofthebusinesslogicwouldbemovedtoPlainOldJavaObjects(POJOs)forunittestingpurposes,butinpracticesomeofthatlogicendsupinthesubviewsorfragments.

    OftenActivitiesareusedasanintermediarybetweencomponents(e.g.Fragments)becauseyoudon'twantthemtalkingdirectlytoeachother.Byusingthelistenerpatternorasystembus,suchasOtto,thecomponentscanpostamessageandtheActivitywillreaditandrespond.Thiskeepstheconcernsseparateandeasiertomaintaintheindividualcomponents.

    Youcanstartanactivityinsideahostingactivityandgetresultsfromthatactivity.

    YouusestartActivityForResult()tostarttheactivity.Intheactivitythatwasstarted,youusesetResult()tosettheresultthatwillbereturned.Whenbackinthecallingactivity,youchecktheresultcodeandrespondappropriately.

    Agreatexampleofthisisinvokingthesystemcameraandthenprocessingwhetherthepicture-takingeventwassuccessful:http://developer.android.com/guide/topics/media/camera.html

    Activities

    CodeExample

    Activity'sRole

    ActivityResults

  • Thelooselycoupledcomponents(e.g.activitiesandservices)arestitchedtogetherbytheAndroidManifest.xmlfileatruntime.Thisfiledescribeseachofyourcomponentsandhowtheyworktogether.Youdon'tregisterfragmentsherebecausetheyaretransientandtiedtotheactivitythathoststhem.

    Inthisfileyouspecifywhichactivity(oractivities)thatarelaunchable.Youcanspecifyhowthingsarelaunched,howtohandleorientations,testingapplicationinformation(whenusinginstrumentation),andhowtohandletheSDcard.Finally,youspecifymetadataabouttheapplicationlikethename,versionname,versioncode,icon,andtheme.

    Thepackagespecifiesthepackagestructureforyourapplicationandisusedtouniquelyidentifyyourapplicationinthemarket.

    Theapplicationlabelreferstoastringresourcethatwillbeshownonthelaunchgridofthedevice.Usingastringresourceallowsyoutocustomizeforinternationalization.We'llcoverresourcesmoreindepthlater.

    TheversionNameisapublic-facingnamefortheversionoftheapplication.TheversionCodeisanintegervalue.Youshouldincreaseitforeachreleasetothemarketandgenerallywhendevelopingtheapplicationanddoinginternalreleases.TheversioncodecombinedwiththesignatureandpackagenameiswhattellsAndroiddeviceusersthatthereisanupdatefortheirphone.

    Insidethetag,youspecifytheactivitiesandservicesthatyouwilluseintheapplication.

    Ifyoucreateanactivityanddon'tregisteritinthemanifest,youwillgetacrashwithasurprisinglyhelpfulerrormessage.

    ThisfileisalsousedasafilterbytheGooglePlaystore.Youcanspecifyapplicationpermissions,whathardwarefeaturesyourequire,andwhatOSversionsyousupport.

    Iftheuser'sdevicedoesn'tsupportoneofyourrequirements,thenitwon'tbeshowninsearchresultswhentheysearchonthedevice.Iftheysearchontheweb,theywillfindyourapp,butwon'tbeabletoinstallondevicesthatdon'tsupportyourapplication'srequirements.

    Youcanfindmoreaboutfilteringinthestorehere:http://developer.android.com/google/play/filters.html

    AndroidManifest.xml

    Example

    ManifestFiltering

  • LayoutsarewhereyoudefinetheviewofyourapplicationusingbuiltinAndroidviews,viewgroups,and/oryourowncustomviewsbasedonthem.TheseXMLfilesliveinyourres/directory.Writinglayoutsthiswayallowsustodecouplethepresentationlayerfrombusinesslogic.

    AlthoughyoucouldwriteallyourviewsinJava,thatmakesitalothardertoleveragethefullpowerofresourcesystem.Plusitoftenbecomesamaintenanceissue.

    Thereisalwaysoneparentattherootofthelayoutandthelayoutmaycontainmanyviews.

    ...

    Therearemanyprebuiltitemsthatyoucanuse,includingButton,TextView,ImageView,grids,andmore!

    YougiveeachviewanidsothatyoucanwireuptologicintheJavaclassthatpointstothisview.ThesystemgeneratesanR.javafilebehindthescenesthatmapsyourresourcesandviewstoaJava-accessibleconstruct.Thisisgeneratedatcompiletime,butthedecisionofwhichviewtoshowisdeterminedatruntime.

    Note:SometimestheR.javafilesgetsoutofsyncwithyourviewsandresources.Thisoftenhappensifyouchangealotinasmallamountoftime.Ifyoustartseeingweirdclasscastexceptions,thenthismaybeyourculprit.

    Inthisexample,theviewactivity_buttonisdefinedinactivity_loosely_coupled.xmlwithanid:

    Intheactivity,youusesetContentView()tospecifywhichlayouttouseandAndroidbringsittolife.Afterthat,youcanaccessitssubviewswiththeidyougaveitintheXMLfile.

    findViewById(R.id.activity_button).setOnClickListener(newView.OnClickListener(){

    Layouts

    Example:activity_loosely_coupled.xml

    XMLviews

    Referencingintheactivity

  • @OverridepublicvoidonClick(Viewv){startActivity(createViewSystemIntent());}};}

    InthisexamplelayoutwecanmaketheactivitybuttondosomethingbyreferencingitinonCreate().Hereweattachaclicklistenerthatwillopenanotheractivity.

    Youcanchangeallmannerofinformationabouttheviews.Goodexamplesaresettingthetextorcolorstodisplay,animatingviews,and/orattachinguseractions.

    TheXMLgetsturnedintoJavacomponentsatruntimewhentheAndroidsystem"inflates"theview.

    Asshownabove,withanActivitytheinflationoccursinthelifecyclemethodonCreate()withthesetContentView()function.

    It'salittledifferentinFragment'sbecausetheinflationoccursinthelifecyclemethodonCreateView()byusingtheinflate()function.

    Whenviewsareinflated,theyareaddedtotheviewhierarchy.Anytimethatyouaddsubviewsorviewgroups,youaredeepeningthehierarchytreethatrepresentsyourviews.YoucanusetheHierarchyViewertooltooptimizeviewsthatareloadingslowly.

    AlloftheviewcomponentsareJavaclasses,whichmeanstheycanbeextended!

    Youcanaddcustombehaviorwhenabuiltincomponentsprovidesome,thoughnotallofthebehavioryou'dlike.Youcanalsocreatecustomviewsthatarecollectionsofthebasicviewtypes.

    Forexample,sayyouwantedtocreateadateandtimeclock.YoucouldcreateaviewthatcombinesaTextViewforthedateandandimageorothercontroltoshowananalogversionofthetime).

    Theseviewsareonlylimitedbyyourimagination!Wewon'tbecoveringthemindepthinthisclass,butthere'sanexcellentpresentationbyChiu-KiChan:CustomComponents.

    Inflation

    Customviews

  • AwaytoorganizeandsimplifyyourXMLlayoutsistouseviewgroups.Youcanusethemtoholdchildrenviewsandmakereusablecomponents.Youcanalsoextendthemtoaddyourownbehavior.

    Herearesomeofthemostcommonlyusedoptions.

    Thisisthesimplestoftheviewgroups.It'sdesignedtoholdonechildview.Thislayoutisoftenusedasaholderfordynamicfragments.

    Asthenameimplies,withthisnameyoulayviewitemsoutinaline,eitherverticallyorhorizontally.

    ViewGroups

    FrameLayout

    LinearLayout

  • Withthisviewgroup,youcanlayoutelementsinarelativefashion.Forexample,placethestartotherightofthecircleandtheheartbelowthecircle.

    RelativeLayout

  • Withthisviewgroup,youcanlayoutsimilarelementsinagridfashion.ThisavailableinlaterOSversionsandhasbeenbackportedforolderOSversions.

    GridLayout

  • ViewStubs

  • Whenyourviewsstarttogetcomplicated,youcanbreakitupusingviewstubs.Thiscanbeusedtolazilyinflateviewsatruntime.

    Moreinformationhere:http://developer.android.com/reference/android/view/ViewStub.html

  • Anactivityisthestartingpointforascreen,butifweputalltheviewsandtheirlogictogetheritquicklydissolvesintoahugemess!Amuchbetterwaytoconstructyourviewsiswithfragmentstofurtherencapsulatetheviewlogicintoself-containedpieces.

    Itbreaksthelogicoftheactivityupintoself-containedpiecesthathandleuserinput.Thisisgreatforalotofreasons.Itletsyoureusethesecomponentsinotherlayoutstosupportdifferentformfactorswithoutchangingcode,justconstructinganewlayoutwithadifferentarrangementoffragmentsandviews.

    Activitiesholdfragments,whichcan'tliveoutsideahost.Theactivityreactstonotificationsfromthefragmentthattheviewshouldbealtered.ThefragmentholdsareferencetothehostingactivityandcanaccessitbycallinggetActivity().

    Considertheexampleapplicationabove.Thetabletversionhasalistofarticlesontheleftsideofthescreenandadetailpaneontheright.Thephonesusestwoseparateactivitiestoshowtheseviews.

    Whenauserselectsanewarticletoview,thefragmentontherightshouldupdate.Youwouldn'twantthearticledetail,suchasanarticleaboutDoctorWho,toberesponsibleforupdatingtheviewtoshowanarticleaboutcats.

    Italsodoesn'tmakemuchsenseforthelisttoknowalotofinformationaboutthedetailit'sgoingtoshow.HereyouwouldusetheActivitytodeterminewhichdetailviewnext.Thisbecomesimportantwhenyoualsohaveaphoneimplementationthatwouldappearintotallydifferentactivities.

    So,howdowedoit?Whentheusertapsanarticleinthelist,aneventistriggeredandtheActivityrespondstothisreceivedevent.Inthecaseofthetablet,itwillsimplyupdatetherightpane.Inthecaseofthephone,itwouldstartanewactivity.

    Fragmentsweren'talwaysaround.TheyintroducedafewyearsagowiththefirsttabletsandHoneycomb(Android3.x).

    Fragments

    MasterDetailPattern

    TheGreatSchism

  • Dashboard,July2014:https://developer.android.com/about/dashboards/index.html

    ItmakesitcomplicatedtosupportthefullrangeofOSversions,butit'sbecomingmoreandmorecompellingtosunsettheolderversionsastheirpercentagecontinuestodrop.Asofthewritingofthisbook,thepercentageofOSesinthewildthatdon'tincludeFragment'sisonly14%(combinedpercentagesofFroyoandGingerbread).

    However,ifyoudointendtosupportolderversions,theyhavebackporteditallthewaybackto1.6usingthesupportlibrary.

  • InthislabwewilllearnabouttheAndroidvisualparadigmsbyexploringthedesignsofexistingapplications.Thiswillhelpusdevelopaprocessforbreakingdownadesignintoimplementablepieces.Thiswillcomeinhandywhenstartingnewscreens.

    Afterwefinishthislab,we'llbereadytostartbuildingourapplication.

    Pleaserefertotheclasshandoutforparts1,2,&3.Asolutionhandoutdetailshowthedesignscouldbebrokendown.

    Let'sgetfamiliarwiththeAndroiddesignsite:

    http://developer.android.com/design/building-blocks/index.html

    Thisexcellentresourceliststheitemsyoucanuseaswellasbestpracticesfortheplatform.Wewon'tbecoveringAndroiddesignindetail,butthisresourceisagreatstartingplaceforunderstandingthedesignlanguageoftheplatform.

    MakesuretocheckoutMaterialDesignresourcestoseewhatiscomingwiththeLreleaselaterthisyear!CheckoutthisvideoformoreinformationontrainsitioningfromHolotoMaterial.

    Note:Seetheappendixformoredesignresources.

    Whatdoyoufindinterestingaboutthedesignlanguage?Howdoesitdifferfromotherplatforms?Canyouthinkofotherplatformfeaturesthatdon'tfeelathomeonAndroid?Doyoufindthenavigationparadigmsintuitive?WhatdoyouthinkoftheevolutionofAndroid'sdesignthroughtheages?WhatdoyouthinkofMaterialDesign?Hadyouheardanythingaboutitbeforetheclass?

    We'llbreakdownthedesignoftheGoogleMusicappasaclass.

    Pleasepairup,analyzetheview,andidentifyviewcomponentstheymayhaveusedtoconstructthisview.

    Let'sstartourcalculator!

    WorkwithyourpartnertoidentifyatleasttwodifferentwaystoyoucouldbreakdownthisviewintoXMLcomponents.We'llstartimplementingsoon!

    Thenexttimeyou'rebreakingdownadesign,thinkabouthowyoucansegmentitintoviewsandfragmentstobestsupporttheuserexperienceyouaregoingfor.

    Lab:DesignChunking

    AndroidDesign

    DiscussionQuestions

    Part1:ClassDesign

    Part2:PairDesign

    Part3:ClassProject

  • We'llworkthroughthisexercisetogetherasaclass.

    Handout:DesignChunking

    Part1:GoogleMusic

  • Pleasepairup,analyzetheview,andidentifyviewcomponentstheymayhaveusedtoconstructthisview.

    Part2:Twitter

  • WorkwithyourpartnertoidentifyatleasttwodifferentwaystoyoucouldbreakdownthisviewintoXMLcomponents.

    Chooseyourfavoriteapplicationandbreakdownseveraloftheirscreensintodesignchunks.It'sagreatwaytolearnfromothers!

    Part3:Calculator

    ExtraCredit

  • TheyuseActionBar(transparent),withatitleofthealbumandoneicon(search).

    Solution:DesignChunking

    Part1:GoogleMusic

  • TheactionbaroverlaysanImageViewfortheartist.Belowthatisanimageofthealbumwe'reviewing.TotherightofthealbumisalbuminformationdisplayedinTextView'sandseveraloptionsavailablejusttotherightofthealbumcover(eitherButton'sorImageView's).ThisislikelyaRelativeLayoutsincethingsarelaidoutrelativetootheritemsonthescreen.

    UnderthealbuminfoisthelistofsongsforthisalbuminaListView.EachlistviewitemisfairlysimplecollectionofTextView'sandanImageViewforalbumoptions.There'sanImageViewthatshowsonarowonlyifthesongiscurrentlyplaying.

    Note:Whenscrollingdowninthelistofsongs,thealbumandartistinformationispushedoffthescreensothatyoucanfocusonthemostrelevantinformation.Thiswouldbeacustomimplementationtoaddthisbehavior.

    Attheverybottomofthescreen,thereisacustomviewthatallowsyoutoplay/pausethecurrentsongoropenthefullsongviewthathasahostofotheroptions.

    Note:Thisviewispersistentthroughouttheapplicationevenifyoubrowseotheralbums.

    There'salotgoingoninthisdesign!

    Twitteralsousesanactionbarwithicons,notitle,andanoverflowmenu.Theyuseatabcontrollerjustbelowtheactionbarforthedifferenttweetstreams,whichhasaindicatorforthecurrenttab.

    Part2:Twitter

  • YourtweetstreamisdisplayedinaListView.Eachtweetishasseveralpiecesofdata,suchastextviewsandimagesthatrepresentretweets,authors,timesinceposting,etc.

    Atthebottomofthescreen,theyhaveacustomviewthatcombinestwobuttonsforpostingimagesandanEditText(customimplementation)forenteringanewtweet.

    Clickingonmostoptionstakesyoutoanotheractivity.

    Therearemanyvalidwaystobreakdownadesign.Eachchoicehasconsequencesorbenefitswhenwebuildouttheapplication.

    Inourclassimplementation,we'llbeusingtwoFragmentslaidoutinaLinearLayoutwithandroid:orientation="vertical".

    Part3:Calculator

  • TheDisplayFragmentwillhandlethedisplay.We'lluseanEditTexttodisplaythenumbersenteredintothecalculatoraswellascalculations.

    TheButtonFragmentwillcontainandcontrolthecalculatorbuttons.We'lluseaRelativeLayouttopositionmanyButton'sforoperationsandnumbers.

    Whatwasyourdesign?Howdoesitdiffer?Howdoyouthinkthatwillimpactimplementation?

    DiscussionQuestions

  • Ensuretheactivityandviewelementsarenotnull.Ensureexpectedfragmentandviewelementsarevisibleonthescreen.Ensurethattheproperresourcesareusedforviewelements.Ensureitemsarehiddenwhenexpected.Ensuretoastsareshown.Ensurethatyourintentstartsthecorrectthing.

    Lab:ConstructTheView

    TestingReminder

  • Let'sdothistogetherasaclass.

    publicclassDisplayFragmentextendsFragment{@OverridepublicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){Viewlayout=inflater.inflate(R.layout.display,container,false);returnlayout;}}

    TheXMLviewdoesn'texist,sowe'llcreateafilecalleddisplay.xmlinthesrc/layout/folder.We'lladdthespecificsoftheviewlater.

    @RunWith(RobolectricTestRunner.class)

    publicclassDisplayFragmentTest{@TestpublicvoidshouldNotBeNull()throwsException{DisplayFragmentfragment=newDisplayFragment();startFragment(fragment);assertNotNull(fragment);}}

    Atthispointweshouldbeabletorunthetestsuccessfully.

    Let'saddourfragmenttomain.xml(layoutfilespecifiedinsetContentView()oftheCalculatorActivity).

  • android:name="com.mobiquity.calculator.DisplayFragment"android:layout_width="match_parent"android:layout_height="wrap_content"/>

    @TestpublicvoidshouldHaveDisplayFragment()throwsException{assertNotNull(activity.getFragmentManager().findFragmentById(R.id.display_fragment));}

    Makesuretorunthetestsandthencommityourworktoyourrepository.

    Testpresenceintheactivity

    Test&commit

  • Yourturn!Pleasecompletethistaskwithyourpartner.

    publicclassButtonFragmentextendsFragment{@OverridepublicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){Viewlayout=inflater.inflate(R.layout.buttons,container,false);returnlayout;}}

    TheXMLviewdoesn'texist,sowe'llcreateafilecalledbuttons.xmlinthesrc/layout/folder.We'lladdthespecificsoftheviewlater.

    @RunWith(RobolectricTestRunner.class)

    publicclassButtonFragmentTest{@TestpublicvoidshouldNotBeNull()throwsException{ButtonFragmentfragment=newButtonFragment();startFragment(fragment);assertNotNull(fragment);}}

    Let'saddourfragmenttomain.xmlbelowtheDisplayFragment.

    Lab:AddButtonFragment

    CreateButtonFragment.java

    Createtheview

    CreateButtonFragmentTest.java

    Addtoview

  • @TestpublicvoidshouldHaveButtonsFragment()throwsException{assertNotNull(activity.getFragmentManager().findFragmentById(R.id.buttons_fragment));}

    Makesuretorunthetestsandthencommityourworktoyourrepository.

    Testpresenceintheactivity

    Test&commit

  • ReplacetheLinearLayoutfrompreviousstepswiththisEditTextindisplay.xml.

    Wecandothissinceeachviewexpectsonlyoneviewattheroot,butmayhavemore.Sinceourviewissosimple,thereisnoneedtohaveanenclosingviewgroup.

    HereI'veaddedmanyXMLattributes!Theattributesaremostlyselfexplanatory,butI'dbehappytoansweranyquestionsonparticularattributes.

    We'lllearnmoreaboutabstractingsomeofthehardcodedvaluesoutlaterintodimensionsandstyles.

    ForthebackgroundcolorI'musingabuiltinAndroidresource:

    android:background="@android:color/white"

    ForthetextcolorIdefinedanewcolorinres/values/colors.xml:

    #ff313131

    Wegoingtorefactorabitheretomakeiteasiertotestnewitems.First,makeafield,fragment,forthefragmentundertest.Then,movethefragmentinitializationandfragmentstartingtothesetUp()function.

    publicclassDisplayFragmentTest{privateDisplayFragmentfragment;

    @BeforepublicvoidsetUp()throwsException{

    Lab:DisplayView

    Addtheview

    Addcolors.xml

    AddtesttoDisplayFragmentTest.java

  • fragment=newDisplayFragment();startFragment(fragment);}

    @TestpublicvoidshouldNotBeNull()throwsException{assertNotNull(fragment);}}

    Nowwe'rereadytoaddthenewtest:

    @TestpublicvoidshouldHaveDefaultDisplay()throwsException{EditTextdisplay=(EditText)fragment.getView().findViewById(R.id.display);assertViewIsVisible(display);assertThat(display.getText().toString(),equalTo(""));}

  • Inthislabwe'lladdthebuttonstotheviewcompletewithtests.

    Note:Theywon'tbeprettyandtheywon'tdoanything!

    AsIbuildeachkey,Iwriteatest.ThenIaddthenextkey.Itypicallydon'tstartlayingouttheviewsormakingthemprettyuntiltheyareallpresentintheviewandthetestsarepassing.Icommitaftertheviewsarepresent.ThenIdoastylingcommitafterward(we'lldothatasaseparatestep).

    Lastwesawthisfile,wehadalltheinitializationcodeinthethetestthatwewrote.Let'smakeafieldforthefragmentandmovetheinitializationtothesetUp()function:

    privateButtonFragmentbuttonFragment;

    @BeforepublicvoidsetUp()throwsException{buttonFragment=newButtonFragment();startFragment(buttonFragment);}

    Nowwecanaddanewtest.

    WeusegetView()togetareferencetotheviewandthenfindthespecificid.

    @TestpublicvoidshouldHaveOneKey()throwsException{assertViewIsVisible(buttonFragment.getView().findViewById(R.id.key1));}

    Nowweaddthebuttontotheview.

    It'sbestpracticetomoveyourstringstothestrings.xmlfileinsteadofleavingthemhardcodedintheview.Italsomakesiteasiertotestthatthecorrectstringisconfiguredforaview.

    1

    Lab:AddButtons

    Testing

    Addatest

    Addabutton

    Addastring

  • Thelinttoolwillrecommendthisforyoubyshowingyellowbarsandalightbulbintheview.

    Let'sextendourtesttoensurethatthecorrectstringisconfiguredfortheview.We'lluseourResourceLocatorclasstogettheresourcestringandcompareittoTextView'sgetText()returntoensuretheyareequal.

    Ourfinaltestlookslikethis:

    @TestpublicvoidshouldHaveOneKey()throwsException{TextViewkey1=(TextView)buttonFragment.getView().findViewById(R.id.key1);assertViewIsVisible(key1);assertThat(key1.getText().toString(),equalTo(ResourceLocator.getString(R.string.key1)));}

    Addeachnumberandoperatorkeyinturnandmakesurethetestspassalongtheway.Afteryou'redonewiththebuttons,commit.

    Let'sreplaceourparentLinearLayoutwithaRelativeLayoutsothatwecandefinethepositionofthebuttonsrelativetotheotherbuttons.

    Pleaserefertothescreenshotoftheexampleprojecttodeterminewhereeachbuttonshouldbepositioned.

  • android:id="@+id/key4"android:layout_width="60dp"android:layout_height="60dp"android:layout_margin="5dp"android:layout_below="@id/key1"android:text="@string/key4"/>...

    Note:Therearemanywaysthisviewcouldbelaidout.RelativeLayoutisn'tthemostintuitivechoice,butitisquiteusefulandmasteryofitearlyinyourAndroidcareerwillleadtogreatthings.

  • AccordingtoMeieratKindlelocations2459-2461,youdefineyourownapplicationimplementationwhenyouneedto:

    RespondtoapplicationleveleventsbroadcastbytheAndroidruntimesuchaslowmemoryconditions.Transferobjectsbetweenapplicationcomponents.Manageandmaintainresourcesusedbyseveralapplicationcomponents.

    Youdeclareyourapplicationinthemanifestandtheapplicationclasswillbeautomaticallyinstantiatedwhentheapplicationisrun.

    It'sbestpracticetodeclareyourapplicationasasingleton.

    Application

    Declaration

  • Let'saddthefollowingattributetoourtagofourAndroidManifest.xml.

    CreateafilecalledCalculatorApplication.javainthepackagestructure.YoucanusetheIDEtocreateitforyouordoitmanually.

    It'sbestpracticetosetitupasasingleton.

    publicclassCalculatorApplicationextendsApplication{privatestaticCalculatorApplicationinstance=newCalculatorApplication();

    publicstaticCalculatorApplicationgetInstance(){returninstance;}}

    CreateafilecalledCalculatorApplicationTest.javainyourtestpackagestructure.YoucanusetheIDEtocreateitforyouordoitmanually.

    Let'saddthebasicnon-nulltest:

    publicclassCalculatorApplicationTest{@TestpublicvoidshouldNotBeNull()throwsException{assertNotNull(CalculatorApplication.getInstance());}}

    That'sit!Nowwecanaddmoreitemstothisclassasweneedthem.

    Let'scommitourchanges.

    Lab:AddApplication

    Addtothemanifest

    Createclass

    WriteTest

  • Eventbusesareagreatwaytodecoupleourcomponentswithoutusingainterfaceorlistenerpatternthatcanproducealotofboilerplatecode.

    Ottoisasystem-widenotificationsystem.Acomponent(e.g.anActivityorFragment)postsanevent,withanoptionalmessage,toOtto.Othercomponentsthathaveregisteredforeventswillreceivetheeventandreactasappropriate.

    Let'saddanOttoBus!

    Ifnotalreadypresent,addthemavendependencytoyourpom.xmlfilesothatwecanreferenceOttothroughoutourproject.

    com.squareupotto1.3.4

    NowaddtheselinestoourCalculatorApplication.javaclass.

    privateBusbus;

    publicBusgetBus(){returnbus;}

    publicstaticvoidpostToBus(BaseEventevent){//Note:AutoGeneratingBaseEventnextgetInstance().getBus().post(event);}

    @OverridepublicvoidonCreate(){super.onCreate();instance.bus=newBus();}

    ThefunctionpostToBus()givesusaconvenientwayposttothebusfromanyactivityorfragmentinourapplication.IfwebuildallofoureventstoextendtheBaseEventthenwecanusethisforalleventsintheapplication.

    CreateafilecalledBaseEvent.java.Isuggestcreatingapackagecalledeventstoholdeventsandcreatefurtherpackagesasneededtokeepyourcodeorganized.

    Theeventcanbequitesimple,oryoucanincludedatawithyourevents.Inthiscase,wewillmakeitasbasicaspossible:

    publicclassBaseEvent{}

    Lab:EventBus

    IntegrateOtto

    Applicationbus

    CreateBaseEvent

  • Let'smakesurethattheBusexistsforourapplication.Firstwe'llneedtomigrateourapplicationtoafieldandinitializeinsetUp().Thenwecanaddthistest:

    @TestpublicvoidshouldHaveBus()throwsException{assertNotNull(application.getBus());}

    Onceallthetestspass,committoyourrepository.

    Addatest&commit

  • Meierputsitwell,"usinglayoutresourcesdecouplesyourpresentationlayerfromtheapplicationlogic,providingtheflexibilitytochangethepresentationwithoutchangingcode.Thismakesitpossibletospecifydifferentlayoutsoptimizedfordifferenthardwareconfigurations,evenchangingthematruntimebasedonhardwarechanges(suchasscreenorientationchanges)."

    I'veseenatoomanyduplicatedlayouts,hardcodedvalues,andhardcodedJavaviewsclutteringAndroidapplications!Allofthesepracticesleadtodifficulttomaintainappsandmakesithardertoscaletonewerdevicesandformfactors.However,ifyouleverageAndroidsystemfromthestartandletitdotheheavingliftingforyou,youcanavoidalotofpaindowntheroad.

    AlthoughIfindXMLapaintoreadandwrite,I'vegrowntolovetheresourcesystem.Itisoneofthemostpowerfultoolsyouhavewhenconstructingyourapplication,butisoftenmisunderstoodanddefinitelyunderratedandunderutilized.

    Youplaceyourlayouts,drawables,andvalues(e.g.strings,colors,dimensions)inthisfolder.

    Thebasicfolderstructurelookslikethis:

    res/drawable/values/layout/

    Oneannoyingthingaboutthesefoldersisthatyoucan'tcreatesubfolders.Thisisespeciallyannoyinginthelayoutfoldersinceyouendupwithlotsofviewsinyoursystem.Youcanhowever,makeupyourownfilenamesandgroupresourcesthatbelongtogether.

    There'slotsofgreatinformationonAndroid'ssiteabouthowtosuportmutipleformfactors:http://developer.android.com/guide/practices/screens_support.html

    Meier,Reto(2012).ProfessionalAndroid4ApplicationDevelopment(Loc.2816-2818).JohnWileyandSons.KindleEdition.

    Chapter5:ResourceSystem

    res/

    Resources

  • InAndroid,youcreatestyles(whichisanalogoustoCSS),externalizeyourresources,andusewhatAndroidcallsresourcequalifierstoadaptyourdesigntodifferentformfactors.

    Ifyouhaveawebprogrammingbackground,thiswillfeelfamiliar.Ifnot,theideaisthatyourviewautomaticallyscalestosuittheamountofspaceithasandyoudefinehowthatviewshouldadapttonewsizes.

    Don'tbaseyoudesignsonspecificdevicesordevicecategories,ratherthinkaboutthenaturalseparationorbreakinglinesforyourviews.Thereisno"phone"or"tablet",theyarejustdevicesinacontinuum.

    Responsivedesign,asopposedtopixel-perfectdesigns,fromthestartwillmakeitaloteasiertoscaleyourviews.

    Androiddynamicallyselectsresourcesatruntimethatarebestsuitedtothedevicerunningtheapplication.Youcansetupalternativesforthingslikeorientations,hardware,languages,locations,viewsizes,andmore.ItfreesyoufromtheburdenoffiguringoutincodewhatresourceyoushouldbeshowingifyouuseAndroid'ssystemtodoitforyou.

    Externalizingresources,suchasimages,strings,dimensions,styles,themes,andlayoutmakesitmucheasiertomaintainandscaleyourviews.

    ThisistheheartoftheAndroid-therearenoguaranteesofwhatyourappwillrunon,soyouneedtocreatethemostflexibleappandviewspossibletoavoidheadachesfromhardcodedvalues.

    TheActivityclassprovideshelpermethodstogettheseresourcessuchasgetString(R.string.name)andgetDrawable(R.drawable.name).There'salsoamethodgetResources().SomeoftheseareavailableintheFragmentclassandyoucanalwaysaskfortheactivity'sresourcesbycallinggetActivity().getResources().

    Userelativepositioningwhenlayingoutyourviewssothattheyadaptwellwhenrunningondifferentscreensizes.RelativeLayoutandLinearLayoutaregreatchoices.

    Usewrap_contentandmatch_parentwheneverpossiblewhendefiningthelayout_heightandlayout_widthofyourviews.wrap_contenttellsthesystemtomeasuretheviewatinflationandrenderthewidgetwithjustenoughspacetocontainit.Ontheotherhand,match_parentsaystakeupalltheavailablewidthandheightwhenrenderingthisview.

    DesignPrinciples

    Thinklikeawebprogrammer

    LetAndroiddotheheavylifting

    ExternalizeResources

    ScalableLayouts

  • Stylesandthemesarespecifiedinres/styles.xml.Themesareusedfortheoverallappearanceoftheapplication,whilestylesareappliedtospecificviews.

    Inmostcases,youwon'tneedmorethanonestylefile.Ifyouuseabstracteddimensionsandimageassetsinyourstyles(asopposedtohard-codedvalues)combinedwiththequalifiersystem(allofwhichwillbecoveredindepthinthischapter),itmakesyourviewsscalable.

    Youcaninheritfromotherstylesandthemes.Youcanoverrideattributesandaddnewonesinderivedstylesorwhenspecifyingviewattributesinthelayoutfile.

    Stylesallowyoutoabstractoutviewattributesintoacentralizedlocationtoenablereuse.

    Inthisexample,I'vedefinedastylecalledSquareButtonthatconfiguresaheightandwidth.

    50dp50dp

    Note:Thesyntaxisabitdifferentfromhowyouspecifyviewattributesinyourlayouts,buttheybothusethesameXMLattributes.

    Afteryoudefineastyle,youcanreferenceitintheXMLlayoutbyusingthestyleattribute:

    Note:styledoesn'tusetheandroidnamespace.

    ThemesprovideaconvenientwaytoapplystyletoanentireapplicationorjustanActivity.

    Thisisusefulbecauseyoucanrapidlyreskinyourapplicationbychangingjustafewlinesofcode.

    Touseathemeinyourapplication,youspecifyitintheAndroidManifest.xml.YoucaneitheruseAndroid'sbuiltinthemes(examplebelow)orcreateyourown.

    Styles&Themes

    Styles

    Definingstyles

    Usingstyles

    Themes

  • Ifyouwanttocustomizeatheme,youcanextendanexistingAndroidthemeandaddingattributesoroverrideattributesasdesired.

    AndroidManifest.xml

    styles.xml

    Athemeisjustastyle.Whatmakesitdifferentiswhereyouapplyit!

    ...

  • MyapproachtodimensionsandstyleshasevolvedovertimeasIgetexposedtonewteamsandnewdesigners.I'llshowyouwhatittookmeawhiletodiscoverformyselfinhopesofsavingyousomeheadachesdowntheroad.

    WhenIstartedwithAndroid,theteamandIgleefullythrewhard-codedvaluesallovertheplace,oftenduplicatingvaluesinthesamefile!Notonlydidthislitterthecode,butitmadedebuggingviewissuesmoredifficult.

    ThroughoutthischapterI'llshowyouascalablewaytomanagetheseresources.

    It'sstraightforwardtocreateadimension.You'llneedadimens.xmlfileinres/values/:

    25dp

    Youcanreferencetheminstyles:

    @dimen/my_dimen

    OrinlineinyourXML:

    OreveninJava:

    floatdimen=getResources().getDimension(R.dimen.my_dimen);

    Itmightnotbeimmediatelyapparent,butusingdimensionswithresourcequalifiers(coveredindepthlater)allowyoutocreateresponsivecomponents.You'llseethisinactioninthe"FlexibleDimensions"lab.

    Abstractingcolorsgivesyouaconvenientplacetostoreandnameyourcolorsinsteadofusinghardcodedhexvaluesallovertheplace.Havingnamesassociatedwiththecolorsmakesiteasiertomaintainviewchanges.

    Plusyouhaveanaddedbonusofpreviewsofyourcolorswatchesandacolorpicker(includingdropper!)whenyouareopencolors.xmlinIntelliJ.

    Dimensions&Colors

    Dimensions

    Benefit

    Colors

  • Youcanabstractmanytypesofvalues.Checkoutthisarticleformoreinformation:http://developer.android.com/guide/topics/resources/available-resources.html

  • Let'smakeourcalculatorlooknice!Bytheendofthislabwewillcreateandapplystylestoallofourbuttons.We'llalsocreateastyleforthedisplay.

    ColorScheme

    Numberbutton:#876D13(Brown)Operatorbutton:#668113(Green)Equalsbutton:#268474(Blue)Clearbutton:#B0281A(Red)

    First,createafilecalledstyles.xmlinres/values/.Thisiswhereallofourstylesandthemesliveintheapplication.

    Ifyouanalyzethedesign,you'llnoticethatthebuttonsarebasicallyvariationsonatheme.Theonlyvariantsinthestylearedifferentcolorsandsomebuttonsarewiderthanothers.Sincethesebuttonsaresosimilar,itmakessensetocreateabasicstylethateachbuttontypewillinherit.

    Let'saddthisbasebuttonstyletostyles.xml.

    @dimen/button_dimensions@dimen/button_dimensions@dimen/button_margin@dimen/key_text_size@android:color/white

    Herewe'vespecifiedtheheightandwidthsoftheview,themarginbetweenthebuttons,thecolorofthetext,andthesizeofthefont.Allbutthelastuseabstracteddimen's.We'lladdtheseinthenextsection.Forthefinalitem(textcolor),weuseanAndroidsuppliedcolorinsteadofcreatingourown.

    Nowit'stimetostartusingdimensions!

    Lab:ViewStyles

    Createstyles

    Basebutton

    Createdimensions

  • Startbycreatingthedimens.xmlfileinres/values/.Thenaddthebaselinevaluesfortheview.We'lladddifferentversionsofthisfileinalaterlabtoscaletodifferentscreensizes.

    5dp60dp30sp

    NowthatwehaveBaseButtonandallthedimensionsneededtomakeitareality,let'suseittocreateourNumberstyle.

    Youcaninheritattributesfromparentstylesandaddyourownconfigurationsforthenewlyderivedstyle.

    @color/brown

    Fornowwe'llsetthebackgroundtoaflatcolor.Inalaterlabwe'llextendthisstyletoprovidevisualfeedbackuponuserinteraction.

    Note:Youcanalsoinheritfrommultiplestyles:http://developer.android.com/guide/topics/ui/themes.html#Inheritance

    Let'saddcolorstocolors.xmlforthenewbuttons.TheNumbercolorbrownisshownbelow:

    #876D13

    AnotherbenefitofcreatingstylesisthatitwillcleanupourXMLfiles.Removeanyattributethatiscoveredbythestyle.Here'stheupdated1key:

    Muchcleaner!ImoveasmuchaspossibletostylestokeepmyXMLfileslean.IgenerallyleaveattributesthesourceXMLfilethatrelatetopositioningintheview(e.g.RelativeLayoutpositioning),textforabuttonortextview,andtheid.

    Usingtheinformationabove,createandusestylesforeachofthesekeytypes.Whenyoufinish,theviewshouldlooklikethescreenshot.

    Numberstyle

    Createcolors

    Removeextraattributes

    Operators,Equals,andZero

    Display

  • Finally,cleanupthedisplayviewindisplay.xmlusingastyle.

  • Tosetupalternativelayoutsandresourcestoberesolvedatruntime,youuseresourcequalifiers.

    Qualifierscoverthingslikescreensize(widthandheight),languagesandregions,aspectration,orientation,andOSversionamongothers.

    Checkoutthecompletelistingofqualifieroptionsaswellasdetaileddocumentationonhowresourcesareselected:http://developer.android.com/guide/topics/resources/providing-resources.html

    Inthisexampleres/folder,wehaveanumberofdirectories.QualifiedfolderscanberecognizedbythedashintheirnameandtellsAndroidtousespecificresourcesforspecificinstances.

    res/drawable/values-sw600dp/values-fr/layout/layout-land/

    -frstandsforFrench,-sw600dpmeanssmallestwidthofthedeviceis600dpandhigher,and-landiswherethelandscapelayoutslive.Youcouldcombineseveralqualifiersintoonefolderbyusingadashbetweeneachqualifier.

    There'sabitofAndroidmagicthatselectsthebestversionofyourvieworresourceforthecurrentdevice.Ifyousetuptheparallelfolderstructuretosupportdifferentconfigurations,Androidwillhandletherest.Androidchoosesthebestresourcesatruntimebasedonthedevicethatishostingtheapplication.

    Androidtriestomatchwiththemostspecificresourcequalifiersfirstandthenfallsbacktomoregenericoptions.Ifnoneoftheresourcequalifiersinyourapplicationmatchthehostdevice,thebasicvaluesspecifiedinlayout/,values/,anddrawable/willbeused.

    Makesuretohaveasanedefault!Ifyoudefinesomethinginaspecificqualifiedfolder,suchasanid,andthenruntheapponadevicewithdifferentspecifications,itwillcrashbecauseitwon'tbeabletofindthedefaultvalueatruntime.

    Youmightnotcatchthisduringdevelopmentsinceyouarelikelyusingthesamedevice.It'sgoodpracticetovaryyourtestdevicesandtestingsituationstoexploreunhappypaths.

    Inthecaseoflayouts,ifyouwanttooverridetheviewforaspecificconfiguration,youwillneedtocreateanotherversionoftheviewinaqualifiedfolder,butyouusethesamenameforbothfiles.That'showtheresourcequalificationsystemworks!

    Inthecaseofstrings,dimens,drawables,andotherresources,makesuretousethesamenameinthedefaultandqualifiedpathstooverridethevalueforyournewconfiguration.

    Invalues/strings.xmlIhavestringsforawelcomescreen.

    Qualifiers

    Folderstructure

    Resolution

    Naming

    Example:Internationalization

  • HelloDutchMobileConference!ProgrammedbyCoreyLeighLatislaw

    Invalues-nl/strings.xmlIdefinedthesamename,butputthefileinthequalifiedstructureandchangedthetext.

    HalloDutchMobileConference!GeprogrammeerdedoorCoreyLeighLatislaw

  • Inthislab,we'llusethequalifiersystemanddimensionstoscaleourviewfordifferentformfactors.

    Ifyoudon'thaveaccesstoaNexus5,pleasecreateaninstanceusingGenymotion.

    TheActionBarinthiscasedoesn'thelpourapplicationsincewe'llonlybeshowingonescreenanddon'thaveanyconfigurationornavigationoptions.It'sjusttakingupvaluablescreenrealestate!

    OnnewerOSesyougetitbydefaultunlessyouexplicitlyexcludeitinthemanifestfile:

    Let'screateafoldercalledvalues-w350dpandadimens.xmlinthatfolder.Hereiswhereyou'dputyourvaluesyou'dliketouseonscreenswithatleast350dpinscreenwidth.

    78dp4dp50sp

    164dp

    250dp

    8dp40sp

    Youdon'thavetocopyallthedimensionsoverfromvalues/dimens.xml-justtheonesthatyouareinterestedinoverwriting.

    Iadjustedmydisplaymarginsafteradjustingallmybuttonstomaketheedgeslineupbetter.

    Lab:FlexibleDimensions

    RemoveActionBar

    Alternatedimens.xml

    Adjustdisplay&commit

  • Let'saddJapanesenumbers!

    Createafoldervalues-jaandastringsfileunderthisdirectory.

    Copythecharactersfromhereintoyourstrings.xmlfolderforkeys0-9:http://en.wikipedia.org/wiki/Japanese_numerals

    Robolectricallowsyouconfigurethequalifiersforaspecifictest:

    @Test@Config(qualifiers="ja")publicvoidshouldHaveJa0Key(){verifyKey(R.id.key0,R.string.key0,"");}

    Ihaveahelperfunctiontoreducetheduplicatedcodeforeachkey.Youcouldrefactorthisevenfurtherintoanarraythatyouloopthroughtoverifyeachbutton.

    Buttonkey=(Button)buttonFragment.getView().findViewById(id);assertViewIsVisible(key);

    StringresourceString=getString(stringId);assertThat(key.getText().toString(),equalTo(resourceString));assertThat(expectedString,equalTo(resourceString));

    Buildandchangeyourdevice'slanguagetoJapanesetovisuallyverifytheinternationalizationworked.

    Lab:Internationalization

    Addtests

  • Drawablesaretheimagesinyourapplication.Theseimagescanbein.png,.jpg,.gif,orspecifiedinXML.

    YousavethefilesindrawableoraqualifiedversionofthedrawablefolderandthenreferenceinXMLwithouttheextension.

    Insteadofincludinganimagewithdifferentdensities,youcouldspecifyresourcesinXMLandevenJava.

    Forexample,todrawaredrectangle,youcouldcreateitusingXML.

    You'dsavethefileinthedrawable/folderandgiveitadescriptivenamelikerectangle.xml.Torefertoitincode,youusethesamemethodofreferencing:

    Thisisaspecialfilethatscalestofillaview.Youareabletospecifyhowcertainregionsstretchandwhatregionsshouldstaythesame.

    Drawables

    ColorDrawable,ShapeDrawable,GradientDawable

    9-patch

  • Youcanfindmoreinformationaboutusingandcreatingthesefileshere:http://developer.android.com/tools/help/draw9patch.html

    YoucanalsospecifyhowviewsappearindifferentstatesviaXML.Acommonusageissettingbuttoninteractionstates.Youcandefinewhatitlookslikenormally,whatitlookslikewhenyoupressthebutton,whatitlookslikewhenfocused(e.g.throughakeyboardormouseinteraction).We'llbedoingthisnextinthelab!

    StateListDrawables

  • Startbycreatingthedrawable/folderunderres/.

    Createnumber_key.xmlinres/drawable/.

    Eachitemherecorrespondstoadifferent

    You'refreetochooseyourowncolorsandcustomizethedesign!I'veaddedmycolorsforthedifferentstatestores/colors.xml:

    #ffafb315#ff604613

    Tomakethisallwork,youneedtoassociateitwiththenumberkeys.EdittheNumberstyletoincludethisnewdrawableasourbackgroundimage.

    @drawable/number_key

    Nowourbuttonsrespondtotouches!

    Lab:ButtonState

    Selector

    Colors

    Applyinstyle

  • Dothisforeachtypeofbuttonandcommit.

  • Let'screateaniconforourapplication!

    OpenAndroidAssetStudioandchoose"Launchericons".

    Createanimageofyourchoiceanddownloadthezipfile.Openingthefileyouwillseethatthere'sseveralimagesinsidequalifiedfolders.Moveeachoftheseimagesintothecorrectfoldersandaddqualifiedfoldersthatdon'tcurrentlyexit.Overridetheexistingiconswhenprompted.

    Note:Thetooldoesn'tprovidearesourcefordrawable-ldpi.

    Wealreadyhavethisfilenamespecifiedinthemanifest,sowewon'tneedtoupdatethefile.Ingeneral,Ifyouwanttoaddanicon,addittothetag:

    Commit!

    Lab:AppIcon

  • Anapplication'slifecyclecanbeinterruptedbymanyevents,suchasauseransweringaphonecall.Itisimperativetounderstandwhathappenswhenausernavigatesawayfromyourphoneandthencomesbacksincethiswilllikelyhappenoften.

    It'srarethatauserwillspendsignificanttimeinyourapplicationandprogressthroughthescreensexactlythewayyouenvision.Auseristypicallyquicklyconsumingorsharingcontentandthenmovingontothenextthing.It'slikelythattheuserwillexitandcomebacktoyourapplicationmanytimesaday.Dependingonhowtheyleftyourapplicationandhowyoumanagethelifecycle,itcouldleadtosomesurprisingresultswhentheylaunchyourapplicationthenexttime!

    Weoftenoverlookthisfactwhenwearewritingapplicationsbecausewestareatitforalongtimeandworkthroughtheapplicationinaparticularway(asitwasdesigned).Weenduponlythinkingaboutthehappypathandmissmanybugsthatarisefromimproperlifecyclemanagement.Onlybyinteractingwithyourapplicationasanormaluserwouldwillyoustarttoseethesequirks.

    Anapplicationhasalifecycle.It'sactivitieshavealifecycle.Theactivitymayhostoneormorefragmentsthatalsohavetheirownlifecycles.

    We'llgothelifecyclesofthesecomponentsinfurtherdetailinthischapterandendwithalabtosolidifytheseconcepts.

    Chapter6:ManagingtheLifecycle

  • Calledwhentheapplicationisstarting,beforeanyactivity,service,orreceiverobjects(excludingcontentproviders)havebeencreated.Makeitfast,thisaffectsstartupperformance.

    Whentheoverallsystemisrunninglowonmemory,youusethistotrimmemoryusage.Releaseanycachesorotherunnecessaryresourcesyoumaybeholdingonto.Thesystemwillperformagarbagecollectionforyouafterreturningfromthismethod.

    Calledwhentheoperatingsystemhasdeterminedthatitisagoodtimeforaprocesstoclearupunneededmemory.Thiscanhappenwhentheapplicationgoesinthebackgroundandthereisnotenoughmemorytokeepasmanybackgroundprocessesrunningasdesired.

    Calledbythesystemwhenthedeviceconfigurationchangeswhileyourcomponentisrunning.

    Atthetimethatthisfunctionhasbeencalled,yourResourcesobjectwillhavebeenupdatedtoreturnresourcevaluesmatchingthenewconfiguration.

    ApplicationLifecycle

    onCreate()

    onLowMemory()

    onTrimMemory()

    onConfigurationChanged()

  • Therearemanystates,butinpracticeyouuseonCreate(),onResume(),onPause(),andonDestroy()mostoften.Theactivitygoesthroughthecreationflowwhenstartingupandthenfollowsasimilar(butreverse)teardownflowwhenmovingtothebackground.

    WhenonCreate()iscalled,theactivityisbeingcreated,butnotyetvisibletotheuser.Youcangetreferencestoviewelementsandconfigurelongrunningprocesses.

    WhenonStart()iscalled,theactivityisbeingcreatedandmaybevisibletotheuser,buttheuserwon'tbeabletointeract.

    WhenonResume()iscalled,theactivityisvisibletotheuserandreadyforuserinput.

    WhenonPause()iscalled,theactivityisstillpartiallyvisible.TheusermayhavebeenshownadialogorotheritemthatbrieflytakesthefocusawayfromtheactiveActivity.It'spossiblethattheymayresumetheactivityshortly,butyoushouldstartpreparingfortheteardown.

    WhenonStop()iscalled,theactivityishiddenandmaybecleanedupifresourcesareneededforthenew(andcurrentlydisplayed)activitythatauserisinteractingwith.

    ActivityLifecycle

    ActiveStates

    Created

    Started

    Resumed

    Inactive

    Stopped

    Destroyed

  • onDestroy()iscalledrightbeforeyouractivityisdestroyed.

    Thiscanhappeneitherbecausetheactivityisfinishing(someonecalledfinish()onit,orbecausethesystemistemporarilydestroyingthisinstanceoftheactivitytosavespace.YoucandistinguishbetweenthesetwoscenarioswiththeisFinishing()method.

  • AFragment'slifecycleistiedtoitshostingactivity,buthasindependentmethodsaswell.

    ManyoftheselifecyclemethodsaresimilartotheActivity'smethodsandareintertwinedwiththeActivity'sstate.

    Ifyou'dlikemoreindepthinformationaboutthefragmentlifceycle,checkoutAndroid'sdocumentation:FragmentLifecycleandCoordinatingwiththeactivity.

    Fragment

  • Thisiswhereyouconfigureviewcomponents.

    Afterthisphase,youhaveaccesstotheActivity.

    onCreateView()

    onActivityCreated()

  • Let'saddloggingtothelifecyclemethodstoseewhat'shappeningbehindthescenesinCalculatorActivity,CalculatorApplication,ButtonFragment,andDisplayFragment.

    Sothatwecaneasilyidentifyourlogmessages,addaconstantfieldtoeachclass:

    privatestaticfinalStringTAG="Lifecycle"+[ClassName].class.getSimpleName();

    Makesuretoreplace[ClassName]withthenameoftheclass(e.g.CalculatorApplication).

    UseOtooverridethelifecyclefunctions.

    Addalogcallineachmethod.Forexample,youronCreate()shouldlooklikethis:

    @OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);Log.d(TAG,"onCreate()");...}

    YoucanfiltertheIntelliJlogstoshowonlyaspecifictag(thefirststringprovidedtoLog.d()):

    Lab:VisualizingtheLifecycle

    Tagging

    Instrumenting

    Run

  • Youcannavigateforwardsandbackwardsinanapplication.

    Thebackstackkeepstrackofallnewactivitiesandfragmentsthatwereeitherimplicitlyorexplictlyadded.

    WhenyouusestartActivity()withanintent,itisautomaticallyaddedtothebackstackforyou.Withfragments,youcanexplicitlyaddthefragmenttothebackstackwhencommittingaFragmentTransaction.

    YoucaninterceptbackclicksinanActivity,thoughbecarefulbecauseyoushouldn'tviolateauser'sexpectations.

    @OverridepublicvoidonBackPressed(){...}

    Backstack

    Backbutton

  • WhenFragment'sareaddedtotheviewinanXMLfile,theyarestaticandalwaysvisibletotheuser.Youcan'tmanagethestatedirectly,itistiedtothestateoftheactivity.

    WhenyoucreateFragment'sincode,youcandynamicallymanagethemwiththeFragmentManager.Youmanuallyshow,hide,andreplacefragments.

    TypicallyyoudeclareanXMLplaceholdertohouseyourfragment.ApopularchoiceisFrameLayoutwithanid.IfyouplantouseaFragmentwithoutaview(discussedlaterinthischapter),youdon'tneedaplaceholderlocation.

    FragmenttransactionsoperateonFragments.YoucanbeginonebygettingareferencetotheFragmentManagerandthechangeswilltakeeffectwhenyouusecommit().

    Usingadd(),yousupplytheidofyourfragmentholderandareferencetothefragmentyou'dlikecreated.

    getSupportFragmentManager().beginTransaction().add(R.id.holder,newMyFrag()).commit();

    Insteadofusingfragmentstoencapsulateviewfragments,youcancouldusethemtohandlebackgroundprocessing.

    Todothis,youreturnnullfromonCreate()andaddthefragmentmanually(notinXML)inthehostingactivityusingtheFragmentManager.It'sessentialtouseastringtagtoidentifythefragmentsinceyoudon'thaveanidassociatedwithit.

    Note:YounormallyusethiswithsetRetainInstance(true)toensurethattheFragmentisnotdestroyedonconfigurationchanges.

    Backgroundfragmentsdon'tprovideaviewandarenotattachedaaholderinyourlayout.Whenaddingabackgroundfragmenttothebackstack,youmustgiveita"tag"soyoucanrefertoitagain.Otherwiseyouhavenowaytoretrievethefragmentoncethetransactioniscomplete.

    getFragmentManager().beginTransaction().add(newMyFrag(),"tag").commit();

    Youcanaddfragmentstothebackstack.Todoso,justaddacalltoaddToBackStack(true)beforethecommit()inyourtransaction.

    FragmentManager

    FragmentTransaction

    Addingfragment

    Backgroundfragments

    Backstack

  • CreateCalculatorStateFragment.java.Thisfragmentwillbeabackgroundframentthatwillmanagethestateofourcalculator.Noticethatwearereturninganullviewwhencreatingtheview.

    publicclassCalculatorStateFragmentextendsFragment{@OverridepublicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){returnnull;}}

    Addthenormalfirsttesttoourfragmentfile:

    @RunWith(RobolectricTestRunner.class)

    publicclassCalculatorStateFragmentTest{@TestpublicvoidshouldNotBeNull()throwsException{assertNotNull(newCalculatorStateFragment());}}

    NowaddatesttoCalculatorActivitytoensurethatthefragmentispresent.Itshouldfail!

    @TestpublicvoidshouldHaveCalculatorStateFragment()throwsException{assertNotNull(activity.getFragmentManager().findFragmentByTag("calculatorstate"));}

    We'reusingfindFragmentByTag()sincethisisabackgroundfragment.Whenweaddthefragmenttotheactivity,we'lluseatagsothatwecanreferencethefragment.

    Nowwehaveareasontowritecodeintheactivity.FirsttimethisisstartingtofeellikerealTDD!

    AddanewinstanceofthefragmenttoourActivity'sFragmentManagerviaaFragmentTransactioninonCreate().

    getFragmentManager().beginTransaction().add(newCalculatorStateFragment(),

    Lab:AddCalculatorStateFragment

    Createfragment

    Testfragment

    Testactivity

    AddCalculatorStateFragmenttoCalculatorActivity

  • CALCULATOR_STATE_FRAGMENT_TAG).commit();

    Auto-generateaTAGforthecalculatorstatefragmentusingtheIDE.

    Nowretest-everythingshouldpass.

    Yay,timeforacommit!

    Commit

  • Whenyouwanttosavethestateofviewcomponentsorotherthingsthatarenotstoredinmorepermanentstorage,youwouldusethesaveandrestoreinstancestate.

    Let'ssayyou'rebuildinganapplicationthatsearchesforyourfavoritecity'scuisineandyouhaveanEditTextthatallowsthemtoenterasearchterm.Ifyourotatethedevice,theactivityisdestroyedandrecreatedtherebyusingthetermthattheyhave