"Fungerer efter hensigten"

click fraud protection

Androids tilgængelighedsfunktion er kendt for at forårsage UI-forsinkelse. Er det en fejl, eller er det en funktion? Hvorfor opstår det? Vi hos XDA undersøger årsagen.

Skønheden ved Android ligger i de mange forskellige måder, som tredjepartsapplikationer kan interagere med systemet på. Password manager apps som f.eks LastPass give mulighed for automatisk at feed relevante brugernavn/adgangskode data til næsten enhver login-skærm. Teksthjælper giver dig mulighed for betydeligt at forkorte din tid på at sende sms'er til dine venner ved at give dig mulighed for at oprette tekstudvidelsesmakroer. Native udklipsholder mindsker besværet forbundet med hyppigt at skifte mellem apps for at kopiere store mængder tekst ved at give dig mulighed for at dobbelttrykke på et hvilket som helst inputfelt for at få et udklipsholder frem. Hvem kan glemme Grøngør, måske den #1 mest anbefalede app af entusiaster, som holder useriøse baggrundsapps i skak og dermed kan forbedre batterilevetiden? Endelig, omend mindre bekendt med de fleste brugere, er der

AutoInput - et Tasker-plugin designet til at automatisere skærmtryk, tekstinput, strygebevægelser og meget mere. Disse apps tjener alle vidt forskellige anvendelsestilfælde, men hver af disse apps er afhængige af en meget misforstået del af Android-kernefunktionaliteten: Tilgængelighed.

For den gennemsnitlige Android-bruger kan det virke mærkeligt, at mange af disse fantastiske funktioner, der bruges af din yndlingsapp, styres af en indstilling under tilgængelighed undermenu. At lave en app tilgængelig formodes typisk at betyde, at en Android-app er brugbar for en person med handicap. Så hvorfor i alverden har LastPass, Native Clipboard, Text Aide, Greenify eller AutoInput en tilgængelighed service? Desuden, hvorfor ser det ud til at aktivere en tilgængelighedstjeneste forårsage så meget UI lag? Det ser ud til at være ligegyldigt, hvilken version af Android du er på – uanset om det er det Android 5.0 Lollipop eller Android 7.0 Nougat - fordi forsinkelsen forårsaget af visse tilgængelighedstjenester kan påvirke din oplevelse. En simpel løsning på dette problem er blot at deaktivere tilgængelighedstjenester, du måske har aktiveret - men ved at gøre det mister vi så meget nyttig funktionalitet. En anden løsning er at anmode Google om at "fikse" Androids tilgængelighedsforsinkelse, men Google hævder, at Android Accessibility er det fungerer efter hensigten. Vi har talt med et par udviklere, der er fortrolige med tilgængelighedstjenester og har undersøgt, hvordan funktionaliteten fungerer, og vi er her for at teste denne påstand: er Androids tilgængelighedsforsinkelse en fejl, eller er det en funktion?


Forstå Android-tilgængelighed

Som du måske forestiller dig ved navnet, er tilgængelighed for det meste beregnet til udviklere for at give yderligere funktionalitet til alle brugere med handicap. Faktisk et hurtigt kig over på officielle dokumentationssider for tilgængelighed afslører, at Google har et ret snævert syn på, hvilke slags tjenester der skal leveres af Accessibility Services.

Mange Android-brugere har forskellige evner, der kræver, at de interagerer med deres Android-enheder på forskellige måder. Disse omfatter brugere, der har visuelle, fysiske eller aldersrelaterede begrænsninger, der forhindrer dem i fuldt ud at se eller ved hjælp af en berøringsskærm, og brugere med høretab, som måske ikke er i stand til at opfatte hørbar information og alarmer.

Android tilbyder tilgængelighedsfunktioner og -tjenester til at hjælpe disse brugere med at navigere deres enheder mere nemt, inklusive tekst-til-tale, haptisk feedback, gestusnavigation, trackball og retningsbestemt pad navigation.

Googles Tal tilbage, som kommer forudinstalleret på alle Android-telefoner, er et godt eksempel på, hvordan den 'typiske' tilgængelighedstjeneste formodes at være. Stemmeadgang tager tilgængeligheden et skridt videre og giver mulighed for næsten fuldstændig kontrol over din telefon ved kun at bruge din stemme. Men det faktum, at Google havde til hensigt, at tilgængelighedstjenester skulle bruges på denne måde, forhindrer ikke udviklere fra at implementere dem på den måde, de vil - og det er præcis, hvad udviklere har Færdig. Det er netop på grund af den måde, Accessibility fungerer på, der gør funktionen utrolig nyttig for brugere med eller uden handicap.

For at forenkle tingene lidt, er her en grundlæggende oversigt over, hvordan Androids tilgængelighed fungerer. En udvikler opretter en Tilgængelighedsservice der abonnerer på forskellige Tilgængelighedsarrangementer som sendes af systemet til tjenesten afhængigt af, om visse kriterier er opfyldt eller ej. Når alle tjenester er deaktiveret under Indstillinger --> Tilgængelighed, indsamler eller sender Android ingen tilgængelighedsbegivenheder. Men når brugeren begynder at aktivere tilgængelighedstjenester, begynder Android at overvåge og indsamle kun de tilgængelighedsbegivenheder, som tilgængelighedstjenesten anmoder om. For eksempel en tilgængelighedstjeneste, der abonnerer på tilgængelighedsbegivenheden TYPE_WINDOW_CONTENT_CHANGED vil blive underrettet af systemet hver eneste gang at der sker en ændring i det aktuelle vindue. Endnu en tilgængelighedsbegivenhed kaldet TYPE_VIEW_CLICKED fyrer af hver eneste gang brugeren klikker på en knap af en eller anden art.

Android-tilgængelighedsdemonstration. I denne video har jeg aktiveret appen Tasker at overvåge ændringer i vinduets titel. Dette kræver aktivering af Tasker's Accessibility Service. Du kan replikere dette ved at oprette en ny profil i Tasker med 'Begivenhed'-konteksten sat til 'Variabelsæt' og vælge %WIN som variabel, der skal overvåges. I alt er denne cirka 1 minuts video optaget 107 ændringer i det aktuelle vindue.

Disse former for tilgængelighedsbegivenheder forekommer med stor hyppighed under normal brugerinteraktion. Så forestil dig, hvad der sker, når en bruger aktiverer flere tilgængelighedstjenester der anmoder om, at højfrekvente tilgængelighedsbegivenheder affyres. Det er rigtigt - forsinkelse. For at afbøde dette kan udviklere mere snævert definere, hvilke slags tilgængelighedsbegivenheder deres Tjenesten skal reagere på og i hvilken sammenhæng, såsom muligheden for at begrænse Tjenesten til kun at reagere når i visse apps eller for at begrænse afstemningsperiode mellem begivenheder. Men bortset fra det afhænger mængden af ​​overhead, der genereres af en tilgængelighedstjeneste, mest af hvilke former for tilgængelighedsarrangementer den abonnerer på. I bund og grund vil ikke enhver tilgængelighedstjeneste forårsage forsinkelse. En enkelt tilgængelighedstjeneste, der kræver en højfrekvent hændelse, kan forårsage forsinkelse, især hvis nævnte tjeneste er koblet sammen med en anden tjeneste, der kræver en anden højfrekvent begivenhed overvåges.


Dyk dybt ned i tilgængelighed med APK-teardowns

Som du kunne se fra videoen ovenfor, kan en tilgængelighedstjeneste, der overvåger ændringer i vinduesindholdet resultere i ret mærkbare ændringer i brugergrænsefladens ydeevne på grund af den store mængde af fangede tilgængelighedsbegivenheder, der blev affyret af system. Det er dog ret svært at afgøre præcist, hvor meget overhead, der er forårsaget af en bestemt tilgængelighedstjeneste. Overvågning af LogCat vil generelt ikke bringe dig nogen vegne, da tilgængelighedsbegivenheder kun udskrives til LogCat, hvis udvikleren af ​​tilgængelighedstjenesten vælger at gøre det. Heldigvis, far til alle Android Accessibility Services, AutoInput, gør præcis det. Og LogCat-outputtet er præcis så rodet, som du kunne forestille dig.

AutoInput skjuler ikke sandheden for os. Overhead forårsaget af appen kan være ret enormt afhængigt af hvilke hændelser du overvåger. Men denne overhead er nødvendig for, at appen kan fungere. For at AutoInput kan opsnappe hvert tastetryk, hver skærmbevægelse, hver UI-opdatering og hvert knaptryk, behov at overvåge de respektive tilgængelighedsbegivenheder. Uden disse hændelser kan AutoInput ikke tilsluttes systemet og levere den næsten ubegrænsede UI-automatisering, som det i øjeblikket giver mulighed for. Således giver alle AutoInputs funktioner perfekt mening i forbindelse med tilgængelighed. Men for andre apps skal vi se lidt dybere for at forstå, hvordan deres tilgængelighedstjenester håndteres.

En tilgængelighedstjeneste egenskaber er defineret i en XML-ressourcefil i APK'en. Derfor kan vi udføre en APK-nedrivning på en app med en tilgængelighedstjeneste for at finde ud af tjenestens attributter. Hver app fungerer forskelligt, så jeg vil forsøge at forklare, hvordan deres tjenestes attributter relaterer sig til den specifikke funktion, den udfører.

Native udklipsholder

Native Clipboard er mit valg, når det kommer til klippebordsadministratorer. Hvis du leder efter en meget tilpasselig udklipsholder, er Native Clipboard en ret god app. Den har endda en Xposed Module-komponent, så du kan trykke længe på 'Sæt ind'-knappen for at hente udklipsholderen frem! Desværre, hvis du ikke har adgang til Xposed Framework (såsom alle brugere på Nougat), bliver du nødt til at nøjes for at aktivere tilgængelighedstjenesten, som giver dig mulighed for at dobbeltklikke på en hvilken som helst tekstinput for at få vist udklipsholderen Manager. Her er hvad det indebæ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 Clipboard's Accessibility Service anmoder om at affyre en tilgængelighedsbegivenhed hver gang, der klikkes på en visning, der klikkes længe, ​​fokuseres, eller hvis der er en ændring i vinduestilstanden. Uden at have adgang til kildekoden kan jeg ikke sige præcis, hvordan Native Clipboard fungerer, men det er sandsynligt, at Native Clipboard venter på, at vinduestilstanden indikerer, at det bløde tastatur i øjeblikket er åbent, og derefter overvåger det, om der trykkes på inputtet Mark. Appen har en afstemningsperiode på 100 ms, så det er bestemt hurtigt nok til at reagere stort set med det samme på ændringer i det bløde tastaturs synlighed samt dobbelttryk. Dette kan resultere i nogle UI-overhead, når brugeren bruger det bløde tastatur til at skrive tekst, hvilket potentielt kan resultere i forsinkelse.

Grøngør

Dernæst er alles foretrukne batterisparer, Greenify. Greenify bruger Accessibility Events til at drive sine ikke-rodfunktioner.


"@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 bruger ændringer i Window State til at bestemme, hvornår telefonens skærm er slukket, og det kræver, at du forsinker låseskærmens aktivering ved at ændre en indstilling i sikkerhedsindstillingerne. Greenify vil også modtage begivenheder af typen Annoncering eller Notifikationstilstand ændret, sidstnævnte, hvilket er unødvendigt på Android 5.0+ enheder takket være funktionen Notification Access. Det vil dog stadig modtage disse begivenheder uanset dette faktum. Greenify burde ikke forårsage meget overhead i sig selv, men muligheden består.

Nova Launcher

Sandsynligvis den mest populære tredjeparts launcher-app på markedet, Nova Launcher er et glimrende eksempel på en app, der bruger en tilgængelighedstjeneste med minimal eller ingen overhead. Den eneste grund til Tjenestens eksistens er at hjælpe visse enheder med at udføre bevægelser.


"@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 der ingen tilgængelighedshændelse defineret i XML-filen. Det eneste, der nævnes, er navnet på en pakke - Nova Launcher. Det, der sker her, er en løsning for visse enheder, hvor Nova Launchers bevægelser ikke virker. Denne service vil give Nova Launcher alle tilgængelighedsbegivenheder, der er affyret fra kun i Nova Launcher. Det lyder mærkeligt, men det er tilsyneladende en måde at rette Novas startskærmbevægelser på, hvis din enhed ikke fungerer med dem. Da dette kun anmoder om begivenheder fra Nova selv, udgør tjenesten meget lidt overhead.

LastPass

Endelig, måske den mest berygtede tilgængelighedstjeneste, der forårsager forsinkelse (sandsynligvis på grund af dens enorme popularitet) - LastPass. Spørgsmålet om lag i LastPass er så mærkbar at virksomheden har en tjenestemand FAQ-side, der beskriver problemet. Som det står i ofte stillede spørgsmål, er der intet, du kan gøre ved forsinkelsen, bortset fra at deaktivere tjenesten. Hvorfor virker LastPass's Service så voldsom, når det kommer til lag? Lad os tage et kig på tjenestens egenskaber.


"@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 />

Sandheden er, at der ikke er noget ud over det sædvanlige med LastPass's Service. Den anmoder kun om to hændelsestyper at overvåge - TYPE_VIEW_FOCUSED og TYPE_WINDOW_CONTENT_CHANGED. Den gør dette, fordi den skal vide, hvornår en app/websides indhold ændres/kommer i fokus, og derefter henter den det aktuelle vinduesindhold for at lede efter eventuelle adgangskodeindtastningsfelter. Men da tjenesten konstant gør dette på to ekstremt hyppigt affyrende tilgængelighedsbegivenheder, resulterer det i forsinkelse. Det er den uheldige sandhed.


At leve med Lag

Da vi første gang læste, at Google lukkede fejlrapporter om tilgængelighedsforsinkelse, fordi funktionen "fungerede efter hensigten", var vi lige så forvirrede og oprørte som mange af jer. Men i stedet for at acceptere forklaringen for pålydende, besluttede vi selv at undersøge sagen for at fastslå sandheden. Så da Googleren på fejlrapportsiden sagde dette:

Hej dette problem er vedvarende over Android-udgivelser. Der vil også altid være en ekstra forsinkelse, når en tilgængelighedstjeneste er aktiveret. Det skyldes, at enheden, ud over standardbrugergrænsefladen, leverer en masse information til tilgængelighedstjenester, så de kan give en alternativ brugeroplevelse til disse brugere.

Vi er kommet til at forstå hvorfor dette er tilsigtet adfærd. Apps, der bruger Tilgængelighedstjenester på en måde, der var utilsigtet af Google, vil altid pådrage sig nogle præstationsomkostninger; denne omkostning er simpelthen nødvendig for at give Tjenester den overflod af information, som Android Accessibility affyrer i baggrunden. Androids forsinkelse med Accessibility Services er ikke en fejl, men en funktion. En funktion, som vi bliver nødt til at leve med, medmindre hele systemet bliver omarbejdet, og jeg kan ikke forestille mig, hvordan det ville blive gjort for at rumme så mange forskellige funktionssæt fra så mange forskellige apps.

I det mindste ville LastPass-udviklerne ikke tage dette ned. Deres udviklere har arbejdet sammen med Chromium-udviklerne for at optimere tilgængelighedsstøtte, måske ved at aktivere LastPass-support gennem brug af API'er i stedet for at aktivere en tilgængelighedstjeneste. Optimering omkring de omkostninger, der påløber Accessibility Services er en mulighed, men som mange udviklere implicit har bemærket på Chromium-foraene, er det simpelthen et bandaid, der ikke vil løse det faktum, at utilsigtet brug af tilgængelighedstjenester kan resultere i forsinkelse.


Særlig tak til udvikleren af ​​AutoInput, joaomgcd, for at besvare mange af mine spørgsmål vedrørende tilgængelighed!