400 likes | 497 Views
Android-Programmering. Våren 2014. Oversikt. Ytelse vs responsivitet Strategier for og opprettholde responsiviteten Tråder Asynchronous Task. Ytelse vs responsivitet. Forskjellen på ytelse og responsivitet Ytelse: Hvor raskt er det? Responsivitet: Hvor raskt føles det?
E N D
Android-Programmering Våren 2014
Oversikt • Ytelse vs responsivitet • Strategier for og opprettholde responsiviteten • Tråder • Asynchronous Task
Ytelse vs responsivitet • Forskjellen på ytelse og responsivitet • Ytelse: Hvor raskt er det? • Responsivitet: Hvor raskt føles det? • I brukerorienterte applikasjoner er responsiviteten viktig • Det vi
Android Oppbygning • De fleste applikasjone følger samme oppbygning • Instans av Application klassen • En eller flere instanser av Activity klassen • Flere instanser av View klasser • Meny • Alt dette kjører i en tråd (Main Thread) • Activity, Views, menyer og event handlers
Android Responsivitet • Må holde hovedtråden «åpen» for event handeling • < 200ms • Helst < 100ms • Activity Manager og Windows Manager • Rensponsivitet og ANR (Application Not Responding) errors • Grense på 5 sekunder i hovedtråden
Strategier for og opprettholde responsiviteten • Unngå blokkerende operasjoner i hovedtråden • Bruke ekstra tråder • Bruker servicer
Detektere potensielt blokkerende oppgaver • Unngå blokkerende operasjoner i hovedtråden • Ingen filsystemoperasjoner • Ingen nettverksoperasjoner • Vanskelig og vite hva andre bibliotek og API’er gjør • Strictmode class kan hjelpe • Detektere operasjoner • Vanlig og bruke enableDefaults • Bruk bare under utvikling
Tråder • Ekstra tråder • Bra til potensielt blokkerende oppgaver • Nyttig til mindre oppgaver • Fra 100ms til noen få sekunder • Problematisk til oppgaver lenger enn noen få sekunder • Kan bli drept
Opprette tråder • Bruk Thread klassen til å lage nye tråder • Lag en instans av Thread klassen • Send inn en implementasjon av Runnable interfacet til Thread konstruktøren • Kall Thread.Start • De samme trådproblemene gjelder • Unngå race conditions • Unngå fellesbruk av verdier • Unngå å lage mange små tråder ofte
Tråder og brukergrensesnittet • Kun trygg oppdatering av brukergrensesnitt fra hovedtråden • Helpemetoder • Activity.runOnUiThread • View.post
Prisen for dedikerte tråder • Dedikerte tråder er ikke nødvendigvis beste valget for å forbedre responsiviteten • Koster en del ressurser og lage/bryte ned en tråd • Mye boiler-plate kode
Asynchronous tasks • AsyncTask klassen • Designet spesifikt for og opprettholde responsiviteten • Deler opp arbeidet • Hente informasjon fra brukergrensesnittet og hovedtråden: onPreExecute • Arbeid i en tråd i bakgrunnen: doInBackground • Oppdatere brukergrensesnittet i hovedtråden: publishProgress/onProgressUpdate • Når arbeidet er ferdig, oppdater brukergrensesnittet: onPostExecute • Kjører sekvensielt • Bedre ressursbruk enn dedikerte tråder • Kan bli drept
AsyncTask • AsyncTask er en generisk klasse • Spsifiserer parametere ved bruk av generiske argumenter til AcynTask • Tillater 3 typer parametere • Parametertypen som blir akseptert av execute metoden • Blir sendt internt til doInBackground • Blir sendt inn som en liste med variabel lengde • Parametertypen som sendes fra doInBackground til publishProgress • Samme parameter blir sendt internt til onProgressUpdate • Blir sendt inn som en liste med variabel lengde • Return type fra doInBackground • Blir sendt til onPostExecute som en enkelt parameter
AsyncTask thread pool • API level 1-3 (Android 1.0 til 1.5) • Tasks blir kjørt sekvensielt • API level 4-8 (Android 1.6 til 2.2) • Tasks kan bli kjørt paralellt • API level 9 (Android 2.3) • Alltid kjøre sekvensielt • AsyncTask.executeOnExecutor • AsyncTask.SERIAL_EXECUTOR • Sekvensielt • AsyncTask.THREAD_POOL_EXECUTOR • Paralellt
Oppsumering • Proritere brukergrensesnitt responsivitet • Begrens event handler kode på hovedtråden til 100 ms • Ikke utfør potensielt blokkerende operasjoner • Bruk StrictMode klassen for å avdekke disse operasjonene • Bruk AsyncTask til å frigjøre UI tråden • Tåder og AsyncTask kan bli drept
Oversikt • Long-running operasjoner • Introduksjon til Android services • On-demand service • Bruk av servicer på tvers av prosesser
Long-running operasjoner • Hva mener vi med dette? • Virker subjektivt? • Har en spesifik betydning i Android • En operasjon som tar lang nok tid til at en bruker kan ha byttet applikasjon
Android prosesshåndtering • Android har ansvaret for opprettholde et responsiv brukeropplevelse • Begrensede ressurser • Android må jevnlig terminere prosesser • Prosessen brukeren benytter er prioritert
Tråder og long-running operasjoner • Tråder alene kan ikke håndtere long-running operasjoner pålitelig • Tråder i en Activity er bare viktig for aktiviteten • En Activity prosess kan avsluttes hvis brukeren bytter • Er ikke garantert at tråden blir ferdig • Trenger en måte og prioritere oppgaver uten brukergrensenitt
Android Servicer • Service er en component type i Android • Finnes for å utføre long-running operasjoner som ikke går på UI’et • Høy prioritet • Foran det meste annet enn prosessen brukeren benytter nå • Mulig og elivere en service
Service kategorier • Finnes 2 generelle kategorier • Started Servicer • Kontroll over sin egen livssyklus • Begrenset interaktivitet med andre komponenter • De fleste servicer er started servicer • Bound Servicer • Livssyklus direkte knyttet til komponenten som benytter den • Har mye interaktivitet med komponenten som benytter den
Lage en enkel service • Letteste on-demand started service • Starter når en forespørsel blir sendt • Kjører så lenge forespørselen blir prosessert • Avslutter når den er ferdig • IntentService
IntentService • Håndterer mye av kompleksiteten til servicer • Gjemmer mange av funksjonene til servicer • Håndterer køer av long-running operasjoner • Lager en enkel tråd når startService blir kjørt • Får den flere kall til startService blir dette arbeidet utført sekvensielt • Når en alt er utført, avsluttes den
Lage en IntentService basert Service • Opprette klasse som arver fra IntentService • Konstruktør som kaller IntentService til konstruktør • Override IntentService.onHandleIntent • Utfører arbeidet • Registreres i manifestfilen
Aksessere en on-demand Service • Lag en intent med en referanse til Service komponent klassen • Hvis du ønsker så sende parametere, bruk Intent.putExtra • Kall Context.startService med intenten • Kan kjøre startService flere ganger
Servicer på tvers av prosesser • Seriver er en sentralisert måte å utføre long-running operasjoner • Unngå å tenke på Servicer som tråder • Er en Android component type • Bruker en eller flere tråder til å utføre arbeidet • Kjører i prosessen den blir opprettet i • Kan bli kallt av andre komponenter i samme prosess • Kan bli kallt av komponenter i en annen prosess • Kan håndere flere forespørsler fra forskjellige prosesser samtidig
Gjøre Service tilgjengelig for andre prosesser • Sette opp ett intent filter • Vil vanligvis bruke en Action test • Er en definert string • Bruker som oftest pakke navnet • Filteret kan inneholde Category og/eller Data tester • Kan inneholde flere intent filtere • Android matcher en intent med intent filteret • Starter service prosessen hvis nødvendig • Hvis den kjører brukes instansen som finnes • Intent sendes inn til servicen
Oppsumering • Tråder alene kan ikke håndtere long-running operasjoner pålitelig • Servicer er en pålitelig måte å kjøre long-running operasjoner • Bruk IntentService til å implementere on-demand Started Servicer • Started servicer aksesseres ved hjelp av startService og en Intent • Intent til servicer i samme prosess trenger bare service klassen • Kall til servicer på tvers av prosesser krever Intent Filter
Oversikt • Service livssyklus • Service og tråder • Ta kontroll over livssyklusen
Service livssyklus • Started service kan styre sin egen livssyklus • Ikke begrenset til enkle oppgaver • Kan fortsette og kjøre for å respondere raskere • Kan ha funksjoner som er mer brukerorientert
Service klassen • Arver fra Service klassen • IntentService inneholder en standardimplementasjon for de fleste metoder • Service livssyklusen eksponeres gjennom 3 metoder • onCreate • Kalles når Android lager servicen • Kalles bare en gang • onStartCommand • Kalles hver gang en annen component kaller Context.startService • Kan kalles mange ganger • onDestroy • Kalles for å si at en service blir avsluttet • Component kalles av Context.StopService eller service kaller stopSelf • Kan også kalles av systemet for å frigi ressurser
Started service livssyklus Service Component 1 kaller startService onCreate onStartCommand Component 2 kaller startService onStartCommand Component N kaller stopService stopSelf onDestroy
Implementering av started service livssyklusen • Arver fra Service klassen • Override onCreate • Initialiseringen av Service klassen • Override onStartCommand • Initialiser spesifik request behandling • Vil vanligvis utføre arbeidet i en bakgrunnstråd • Returner et flag som indikerer forventningene til systemet • Override onDestroy • Opprydding • Override onBind • Brukes ikke i started servicer • Return null • Legg til i Android manifest
Servicer og tråder • Kjører i hovedtråden • Den samme tråden som UI’et kjører på • Du har ansvaret for å sette opp arbeidet i en annen tråd • Kan lage tråder eksplisitt • Kan benytte en av klassene som implementerer ExecutorService
Ta kontroll over livssyklusen • En service har 2 mekanisker for å håndtere sin egen livssyklus • stopSelf • En service kan gjøre eksplisitte, eller betingede stopp • onStartCommand • Returnerer verdi som indikerer hva systemet skal gjøre hvis prosessen blir drept
Stop-self • Eksplisitt • Service kaller stopSelf • Systemet kaller onDestroy med en gang og avslutter servicen • Betinget • Service kan indikere at den vil stoppe hvis den ikke har noe arbeid som venter • Hvert kall til onStartCommand inkluderer en request id • stopSelfResult tar request id • Stopper bare hvis det ikke er noen request som venter
Operativsystemets kontroll over livssyklusen • onStartCommand - Returnerer verdi som indikerer hva systemet skal gjøre hvis prosessen blir drept • Kontrollerer automatisk restart av service • Kan restarte når ressurser blir tilgjengelige igjen • Kan vente til neste kall til startService • Kontrollerer hva som sendes til onStartcommand når en restart blir gjort • Kan f.eks. Sende siste intent på nytt
onStartCommand return verdier • Finnes 4 forskjellige • START_NOT_STICKY • Hvis servicen blir drept, ikke start igjen før startService blir kallt • START_STICKY • Hvis service blir drept, restart automatisk når ressurser er tilgjengelig • Sender en null intent til onStartCommand • START_REDILEVER_INTENT • Hvis service blir drept, restart automatisk når ressurser er tilgjengelig • Sender siste intent som ble sendt før den ble drept • START_STICKY_COMPATIBLITY • Kompatabilitet med Android 1.6 og tidligere
Velge riktig onStartCommand return verdi • START_NOT_STICKY • Mindre viktige servicer • START_STICKY • Hvis du ønsker at servicen skal forbli aktiv • Gjør gjerne noe mer enn enkel request håndtering • START_REDILEVER_INTENT • Servicer som er «request-oriented» • onStartCommand flag parameter indikerer om en intent sende inn på nytt • START_FLAG_REDELIVERY • Servicen returnerte fra onStartCommand, men kallte aldri stopSelfResult • Pass på hvis det skaper problemer og håndtere samme intent flere ganger
Oppsumering • Servicer kan håndtere sin egen livssyklus • Servicer kjører i utgangspunktet på hovedtråden • Servicer er ansvarlig for å sende arbeid til bakgrunnstråder • onStartCommand return verdi kontrollerer hva som skjer hvis servicen blir drept