Androids tilgjengelighetsfunksjon er kjent for å forårsake UI-forsinkelse. Er det en feil, eller er det en funksjon? Hvorfor oppstår det? Vi i XDA undersøker årsaken.
Det fine med Android ligger i de mange forskjellige måtene tredjepartsapplikasjoner kan samhandle med systemet på. Passordbehandlingsapper som f.eks LastPass gi muligheten til automatisk å mate relevante brukernavn/passorddata til nesten alle påloggingsskjermer. Teksthjelp lar deg betraktelig forkorte tiden din til å sende tekstmeldinger til vennene dine ved å la deg lage tekstutvidelsesmakroer. Innfødt utklippstavle reduserer bryet med å bytte mellom apper ofte for å kopiere store mengder tekst ved å la deg dobbelttrykke på et hvilket som helst inndatafelt for å få opp en utklippstavle. Hvem kan glemme Greenify, kanskje den #1 mest anbefalte appen av entusiaster, som holder useriøse bakgrunnsapper i sjakk og kan dermed forbedre batterilevetiden? Til slutt, om enn mindre kjent med de fleste brukere, er det AutoInput - en Tasker-plugin-modul designet for å automatisere skjermtrykk, tekstinntasting, sveipebevegelser og mye mer. Disse appene har alle svært forskjellige brukstilfeller, men hver av disse appene er avhengige av en svært misforstått del av kjernefunksjonaliteten til Android:
Tilgjengelighet.For den gjennomsnittlige Android-bruker kan det virke rart at mange av disse fantastiske funksjonene som brukes av favorittappen din, styres av en innstilling under tilgjengelighet undermeny. Lage en app tilgjengelig er vanligvis ment å bety at en Android-app er brukbar for en person med funksjonshemninger. Så hvorfor i all verden har LastPass, Native Clipboard, Text Aide, Greenify eller AutoInput en tilgjengelighet service? Videre, hvorfor virker det å aktivere en tilgjengelighetstjeneste forårsake så mye UI lag? Det ser ikke ut til å spille noen rolle hvilken versjon av Android du bruker – uansett Android 5.0 Lollipop eller Android 7.0 Nougat - fordi etterslepet forårsaket av visse tilgjengelighetstjenester kan påvirke opplevelsen din. En enkel løsning på dette problemet er å bare deaktivere tilgjengelighetstjenester du kanskje har aktivert - men ved å gjøre det mister vi så mye nyttig funksjonalitet. En annen løsning er å begjære Google om å "fikse" Androids tilgjengelighetsforsinkelse, men Google hevder at Android Accessibility er det fungerer etter hensikten. Vi har snakket med noen få utviklere som er godt kjent med tilgjengelighetstjenester og har undersøkt hvordan funksjonaliteten fungerer, og vi er her for å teste den påstanden: er Androids tilgjengelighetsforsinkelse en feil eller er det en funksjon?
Forstå Android-tilgjengelighet
Som du kanskje forestiller deg med navnet, er tilgjengelighet hovedsakelig ment for utviklere for å gi tilleggsfunksjonalitet for brukere med funksjonshemminger. Faktisk en rask titt over på offisielle dokumentasjonssider for tilgjengelighet avslører at Google har et ganske snevert syn på hva slags tjenester som bør tilbys av tilgjengelighetstjenester.
Mange Android-brukere har forskjellige evner som krever at de samhandler med Android-enhetene sine på forskjellige måter. Disse inkluderer brukere som har visuelle, fysiske eller aldersrelaterte begrensninger som hindrer dem i å fullt ut se eller ved hjelp av en berøringsskjerm, og brukere med hørselstap som kanskje ikke er i stand til å oppfatte hørbar informasjon og varsler.
Android tilbyr tilgjengelighetsfunksjoner og -tjenester for å hjelpe disse brukerne med å navigere på enhetene sine mer enkelt, inkludert tekst-til-tale, haptisk tilbakemelding, bevegelsesnavigering, styrekule og retningsfelt navigasjon.
Googles Snakke tilbake, som kommer forhåndsinstallert på alle Android-telefoner, er et godt eksempel på hvordan den "typiske" tilgjengelighetstjenesten skal være. Stemmetilgang tar tilgjengeligheten et skritt videre og gir nesten full kontroll over telefonen ved å bruke bare stemmen din. Men det faktum at Google hadde til hensikt at tilgjengelighetstjenester skulle brukes på denne måten, forhindrer ikke utviklere fra å implementere dem på den måten de vil – og det er akkurat det utviklere har ferdig. Det er nettopp på grunn av måten Tilgjengelighet fungerer som gjør funksjonen utrolig nyttig for brukere med eller uten funksjonshemminger.
For å forenkle ting litt, her er en grunnleggende oversikt over hvordan Androids tilgjengelighet fungerer. En utvikler oppretter en Tilgjengelighetstjeneste som abonnerer på ulike Tilgjengelighetsarrangementer som sendes av systemet til tjenesten avhengig av om visse kriterier er oppfylt eller ikke. Når alle tjenester er deaktivert under Innstillinger --> Tilgjengelighet, samler eller sender ikke Android noen tilgjengelighetshendelser. Men når brukeren begynner å aktivere tilgjengelighetstjenester, vil Android begynne å overvåke og samle inn bare de tilgjengelighetsarrangementene som tilgjengelighetstjenesten ber om. For eksempel en tilgjengelighetstjeneste som abonnerer på tilgjengelighetsarrangementet TYPE_WINDOW_CONTENT_CHANGED vil bli varslet av systemet hver eneste gang at det skjer en endring i gjeldende vindu. En annen tilgjengelighetsbegivenhet kalt TYPE_VIEW_CLICKED fyrer av hver eneste gang brukeren klikker på en knapp av noe slag.
Android-tilgjengelighetsdemonstrasjon. I denne videoen har jeg aktivert appen Tasker å overvåke for endringer i vinduets tittel. Dette krever aktivering av Tasker's Accessibility Service. Du kan replikere dette ved å opprette en ny profil i Tasker med 'Event'-konteksten satt til 'Variable Set' og velge %WIN som variabelen som skal overvåkes. Totalt ble denne cirka 1 minutts videoen tatt 107 endringer i gjeldende vindu.
Denne typen tilgjengelighetshendelser forekommer med stor hyppighet under normal brukerinteraksjon. Så forestill deg hva som skjer når en bruker aktiverer flere tilgjengelighetstjenester som ber om at høyfrekvente tilgjengelighetsarrangementer avfyres. Det er riktig - etterslep. For å dempe dette kan utviklere definere hva slags tilgjengelighetsarrangementer deres Tjenesten skal reagere på og i hvilken sammenheng, for eksempel muligheten til å begrense tjenesten til kun å reagere når inn enkelte apper eller for å begrense valgperiode mellom hendelser. Men bortsett fra det er mengden av overhead generert av en tilgjengelighetstjeneste hovedsakelig avhengig av hva slags tilgjengelighetsarrangementer den abonnerer på. I hovedsak vil ikke alle tilgjengelighetstjenester forårsake etterslep. En enkelt tilgjengelighetstjeneste som krever en høyfrekvent hendelse kan forårsake etterslep, spesielt hvis nevnte tjeneste er kombinert med en annen tjeneste som krever en annen høyfrekvent hendelse overvåket.
Dykk dypt inn i tilgjengelighet med APK Teardowns
Som du kunne se fra videoen som er lagt ut ovenfor, kan en tilgjengelighetstjeneste som overvåker endringer i vinduets innhold resultere i ganske merkbare endringer i UI-ytelsen på grunn av den store mengden fangede tilgjengelighetshendelser som ble avfyrt av system. Det er imidlertid ganske vanskelig å fastslå nøyaktig hvor mye overhead som er forårsaket av en bestemt tilgjengelighetstjeneste. Overvåking av LogCat vil vanligvis ikke bringe deg noen vei, siden tilgjengelighetshendelser kun skrives ut til LogCat hvis utvikleren av tilgjengelighetstjenesten velger å gjøre det. Heldigvis, faren til alle Android-tilgjengelighetstjenester, AutoInput, gjør akkurat det. Og LogCat-utgangen er nøyaktig så rotete som du kan forestille deg.
AutoInput skjuler ikke sannheten for oss. Overheaden forårsaket av appen kan være ganske enorm avhengig av hvilke hendelser du overvåker. Men denne overheaden er nødvendig for at appen skal fungere. For at AutoInput skal avskjære hvert tastetrykk, hver skjermbevegelse, hver UI-oppdatering og hvert knappetrykk, behov for å overvåke de respektive tilgjengelighetshendelsene. Uten disse hendelsene kan ikke AutoInput koble seg inn i systemet og gi den nesten ubegrensede UI-automatiseringen som den for øyeblikket tillater. Dermed gir alle AutoInputs funksjoner perfekt mening innenfor rammen av tilgjengelighet. Men for andre apper må vi se litt dypere for å forstå hvordan tilgjengelighetstjenestene deres håndteres.
En tilgjengelighetstjeneste attributter er definert i en XML-ressursfil i APK-en. Derfor kan vi utføre en APK-nedrettelse på en app med en tilgjengelighetstjeneste for å finne ut tjenestens attributter. Hver app fungerer forskjellig, så jeg vil prøve å forklare hvordan tjenestens attributter forholder seg til den spesifikke funksjonen den utfører.
Innfødt utklippstavle
Native Clipboard er min favoritt når det kommer til utklippstavleadministratorer. Hvis du leter etter en svært tilpassbar utklippstavlebehandler, er Native Clipboard en ganske flott app. Den har til og med en Xposed Module-komponent som lar deg trykke lenge på "Lim inn"-knappen for å få opp utklippstavlebehandleren! Dessverre, hvis du ikke har tilgang til Xposed Framework (som alle brukere på Nougat), må du ta et oppgjør for å aktivere tilgjengelighetstjenesten som lar deg dobbelttrykke på hvilken som helst tekstinntasting for å få frem utklippstavlen sjef. Her er hva det innebærer.
"@string/access_decs"
android: accessibilityEventTypes="typeViewClicked|typeViewFocused|typeViewLongClicked|typeWindowStateChanged"
android: accessibilityFeedbackType="feedbackGeneric"
android: notificationTimeout="100"
android: accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows"
android: canRetrieveWindowContent="true"
xmlns: andro />
Native Clipboards tilgjengelighetstjeneste ber om å avfyre en tilgjengelighetshendelse hver gang en visning klikkes, langklikkes, fokuseres eller hvis det er en endring i vinduets tilstand. Uten å ha tilgang til kildekoden kan jeg ikke si nøyaktig hvordan Native Clipboard fungerer, men det er sannsynlig at Native Clipboard venter på at Window-tilstanden skal indikere at myktastaturet for øyeblikket er åpent, og deretter overvåker det etter trykk på inngangen felt. Appen har en pollingperiode på 100 ms, så det er definitivt raskt nok til å reagere i utgangspunktet umiddelbart på endringer i det myke tastaturets synlighet samt dobbelttrykk. Dette kan resultere i noen UI-overhead når brukeren bruker det myke tastaturet til å skrive inn tekst, noe som potensielt kan resultere i etterslep.
Greenify
Neste opp er alles favoritt batterisparer, Greenify. Greenify bruker Tilgjengelighetshendelser for å drive sine ikke-rootfunksjoner.
"@string/accessibility_service_description"
android: settingsActivity="com.oasisfeng.greenify.accessibility.AccessibilitySettings"
android: accessibilityEventTypes="typeAnnouncement|typeNotificationStateChanged|typeWindowStateChanged"
android: accessibilityFeedbackType="feedbackGeneric" android: notificationTimeout="0"
android: accessibilityFlags="flagReportViewIds"
android: canRetrieveWindowContent="true"
xmlns: andro />
Den bruker endringer i Window State for å avgjøre når telefonens skjerm er slått av, og den krever at du forsinker aktiveringen av låseskjermen ved å endre et alternativ i sikkerhetsinnstillingene. Greenify vil også motta hendelser av typen kunngjøring eller varslingsstatus endret, sistnevnte som er unødvendig på Android 5.0+-enheter takket være funksjonen for varslingstilgang. Den vil imidlertid fortsatt motta disse hendelsene uavhengig av det faktum. Greenify skal ikke forårsake mye overhead i seg selv, men muligheten består.
Nova Launcher
Sannsynligvis den mest populære tredjeparts launcher-appen på markedet, Nova Launcher er et utmerket eksempel på en app som bruker en tilgjengelighetstjeneste med minimal eller ingen overhead. Den eneste grunnen til tjenestens eksistens er å hjelpe visse enheter med å utføre bevegelser.
"@string/accessibility_service_description"
android: accessibilityEventTypes=""
android: packageNames="com.teslacoilsw.launcher"
android: accessibilityFeedbackType=""
android: notificationTimeout="10000"
android: canRetrieveWindowContent="false"
xmlns: andro />
Som du kan se, er det ingen tilgjengelighetshendelse definert i XML-filen. Alt som er nevnt er navnet på en pakke - Nova Launcher. Det som skjer her er en løsning for visse enheter som Nova Launchers bevegelser ikke fungerer for. Denne tjenesten vil gi Nova Launcher alle tilgjengelighetsarrangementer avfyrt fra bare i Nova Launcher. Det høres rart ut, men det er tilsynelatende en måte å fikse Novas startskjermbevegelser på hvis enheten din ikke fungerer med dem. Siden dette kun ber om hendelser fra Nova selv, utgjør tjenesten svært lite overhead.
LastPass
Til slutt, kanskje den mest beryktede tilgjengelighetstjenesten som forårsaker etterslep (sannsynligvis på grunn av dens enorme popularitet) - LastPass. Spørsmålet om lag i LastPass er så merkbar at selskapet har en tjenestemann FAQ-side som beskriver problemet. Som vanlige spørsmål sier, er det ingenting du kan gjøre med etterslepet bortsett fra å deaktivere tjenesten. Hvorfor virker LastPass sin tjeneste så ekstrem når det kommer til etterslep? La oss ta en titt på tjenestens attributter.
"@string/accessibility_service_description"
android: accessibilityEventTypes="typeViewFocused|typeWindowContentChanged"
android: accessibilityFeedbackType="feedbackGeneric"
android: notificationTimeout="200"
android: accessibilityFlags="flagReportViewIds"
android: canRetrieveWindowContent="true"
android: canRequestEnhancedWebAccessibility="true"
xmlns: andro />
Sannheten er at det ikke er noe utenom det vanlige med LastPass sin tjeneste. Den ber bare om to hendelsestyper å overvåke - TYPE_VIEW_FOCUSED og TYPE_WINDOW_CONTENT_CHANGED. Den gjør dette fordi den trenger å vite når innholdet til en app/nettside endret/kommer i fokus, og deretter henter det gjeldende vindusinnhold for å se etter eventuelle passordinntastingsfelt. Men siden tjenesten hele tiden gjør dette på to ekstremt hyppig utløsende tilgjengelighetshendelser, resulterer det i etterslep. Det er den uheldige sannheten.
Å leve med lag
Da vi først leste at Google lukket feilrapporter om tilgjengelighetsforsinkelse fordi funksjonen "fungerte etter hensikten", var vi like forvirret og opprørt som mange av dere. Men i stedet for å akseptere forklaringen for pålydende, bestemte vi oss for å se nærmere på saken selv for å fastslå sannheten. Så da Googleren på feilrapportsiden sa dette:
Hei, dette problemet er vedvarende over Android-utgivelser. Det vil også alltid være en ekstra forsinkelse når en tilgjengelighetstjeneste er aktivert. Det er fordi enheten, i tillegg til standard brukergrensesnitt, gir mye informasjon til tilgjengelighetstjenester slik at de kan gi en alternativ brukeropplevelse til disse brukerne.
Vi har forstått Hvorfor dette er tiltenkt oppførsel. Apper som bruker tilgjengelighetstjenester på en måte som var utilsiktet av Google, vil alltid pådra seg noen ytelseskostnader; denne kostnaden er ganske enkelt nødvendig for å gi Tjenestene den overfloden av informasjon som Android Accessibility skyter av i bakgrunnen. Androids etterslep med tilgjengelighetstjenester er ikke en feil, men en funksjon. En funksjon som vi må leve med med mindre hele systemet blir omarbeidet, og jeg kan ikke forestille meg hvordan det ville blitt gjort for å få plass til så mange forskjellige funksjonssett fra så mange forskjellige apper.
LastPass-utviklerne ville i det minste ikke ta dette av seg. Utviklerne deres har jobbet med Chromium-utviklerne for å optimalisere tilgjengelighetsstøtte, kanskje ved å aktivere LastPass-støtte gjennom bruk av APIer i stedet for å aktivere en tilgjengelighetstjeneste. Optimalisering rundt kostnadene som påløper av tilgjengelighetstjenester er en mulighet, men som mange utviklere implisitt har bemerket på Chromium-forumene, er det rett og slett et plaster som ikke vil løse det faktum at utilsiktet bruk av tilgjengelighetstjenester kan føre til etterslep.
Spesiell takk til utvikleren av AutoInput, joaomgcd, for å svare på mange av spørsmålene mine angående tilgjengelighet!