"Werken zoals bedoeld"

click fraud protection

Het is bekend dat de toegankelijkheidsfunctie van Android UI-vertraging veroorzaakt. Is het een bug, of is het een feature? Waarom komt het voor? Wij bij XDA onderzoeken de oorzaak.

Het mooie van Android ligt in de vele verschillende manieren waarop applicaties van derden met het systeem kunnen communiceren. Wachtwoordbeheer-apps zoals LastPass bieden de mogelijkheid om automatisch relevante gebruikersnaam-/wachtwoordgegevens aan vrijwel elk inlogscherm toe te voegen. Tekst assistent Hiermee kunt u de tijd die u besteedt aan het sms'en naar uw vrienden aanzienlijk verkorten, doordat u macro's voor tekstuitbreiding kunt maken. Inheems klembord vermindert het gedoe dat gepaard gaat met het veelvuldig schakelen tussen apps om grote hoeveelheden tekst te kopiëren, doordat u op elk invoerveld kunt dubbeltikken om een ​​klembord te openen. Wie kan het vergeten Vergroenen, misschien wel de #1 meest aanbevolen app door liefhebbers, die frauduleuze achtergrondapps onder controle houdt en zo de levensduur van de batterij kan verlengen? Eindelijk, hoewel minder bekend bij de meeste gebruikers, is er

Automatische invoer - een Tasker-plug-in die is ontworpen om schermtikken, tekstinvoer, veegbewegingen en nog veel meer te automatiseren. Deze apps bedienen allemaal enorm verschillende gebruiksscenario's, maar elk van deze apps is afhankelijk van een zeer verkeerd begrepen onderdeel van de kernfunctionaliteit van Android: Toegankelijkheid.

Voor de gemiddelde Android-gebruiker lijkt het misschien vreemd dat veel van deze geweldige functies die door uw favoriete app worden gebruikt, worden beheerd door een instelling onder de toegankelijkheid submenu. Een app maken toegankelijk wordt doorgaans verondersteld te betekenen dat een Android-app bruikbaar is voor iemand met handicaps. Dus waarom hebben LastPass, Native Clipboard, Text Aide, Greenify of AutoInput in vredesnaam een toegankelijkheid dienst? Bovendien, waarom lijkt het mogelijk te zijn een toegankelijkheidsdienst mogelijk te maken? zoveel UI-vertraging veroorzaken? Het lijkt niet uit te maken welke versie van Android je gebruikt, of dat nu zo is Android 5.0 Lollipop of Android 7.0 Nougat - omdat de vertraging veroorzaakt door bepaalde toegankelijkheidsdiensten uw ervaring kan beïnvloeden. Een eenvoudige oplossing voor dit probleem is het simpelweg uitschakelen van de toegankelijkheidsservices die u mogelijk hebt ingeschakeld, maar daarbij verliezen we zoveel nuttige functionaliteit. Een andere oplossing is om Google te verzoeken de toegankelijkheidsvertraging van Android te "repareren", maar Google beweert dat de toegankelijkheid van Android dat wel is werken zoals bedoeld. We hebben gesproken met een paar ontwikkelaars die goed bekend zijn met toegankelijkheidsservices en hebben onderzocht hoe de functionaliteit werkt, en we zijn hier om die bewering te testen: is de toegankelijkheidsvertraging van Android een bug of is het een functie?


Android-toegankelijkheid begrijpen

Zoals je je door de naam misschien kunt voorstellen, is Toegankelijkheid vooral bedoeld voor ontwikkelaars om extra functionaliteit te bieden aan gebruikers met een handicap. Inderdaad, een snelle blik op de officiële documentatiepagina's voor toegankelijkheid onthult dat Google een vrij beperkte visie heeft op welke soorten diensten door Toegankelijkheidsdiensten moeten worden geleverd.

Veel Android-gebruikers hebben verschillende mogelijkheden waardoor ze op verschillende manieren met hun Android-apparaten moeten communiceren. Dit zijn onder meer gebruikers met visuele, fysieke of leeftijdsgerelateerde beperkingen waardoor ze hun gezichtsvermogen niet volledig kunnen zien met behulp van een touchscreen, en gebruikers met gehoorverlies die mogelijk geen hoorbare informatie en waarschuwingen kunnen waarnemen.

Android biedt toegankelijkheidsfuncties en -services waarmee deze gebruikers beter op hun apparaten kunnen navigeren eenvoudig, inclusief tekst-naar-spraak, haptische feedback, gebarennavigatie, trackball en directioneel pad navigatie.

Die van Google Praat terug, dat vooraf op elke Android-telefoon is geïnstalleerd, is een goed voorbeeld van hoe de ‘typische’ toegankelijkheidsservice eruit zou moeten zien. Spraaktoegang brengt toegankelijkheid een stap verder en zorgt voor vrijwel volledige controle over uw telefoon met alleen uw stem. Maar het feit dat Google de bedoeling had dat Toegankelijkheidsdiensten op deze manier zouden worden gebruikt, staat dit niet in de weg ontwikkelaars ervan weerhouden om ze op welke manier dan ook te implementeren - en dat is precies wat ontwikkelaars hebben klaar. Het is precies de manier waarop Toegankelijkheid werkt die deze functie maakt ongelooflijk nuttig voor gebruikers met of zonder handicap.

Om de zaken een beetje te vereenvoudigen, volgt hier een basisoverzicht van hoe de toegankelijkheid van Android werkt. Een ontwikkelaar maakt een Toegankelijkheidsdienst die zich op verschillende abonneert Toegankelijkheidsevenementen die door het systeem naar de Dienst worden verzonden, afhankelijk van het feit of aan bepaalde criteria is voldaan. Wanneer alle services zijn uitgeschakeld onder Instellingen --> Toegankelijkheid, verzamelt of verzendt Android geen toegankelijkheidsgebeurtenissen. Maar wanneer de gebruiker Toegankelijkheidsservices inschakelt, begint Android met monitoren en verzamelen alleen die toegankelijkheidsgebeurtenissen waar de toegankelijkheidsservice om vraagt. Bijvoorbeeld een Toegankelijkheidsdienst die zich abonneert op het Toegankelijkheidsevenement TYPE_WINDOW_CONTENT_CHANGED wordt door het systeem op de hoogte gesteld elke keer dat er een verandering in het huidige venster plaatsvindt. Er is weer een toegankelijkheidsevenement gebeld TYPE_VIEW_CLICKED vuurt af elke keer de gebruiker klikt op een of andere knop.

Demonstratie van Android-toegankelijkheid. In deze video heb ik de app ingeschakeld Tasker te monitoren wijzigingen in de venstertitel. Hiervoor is het inschakelen van de toegankelijkheidsservice van Tasker vereist. U kunt dit repliceren door een nieuw profiel aan te maken in Tasker met de context 'Event' ingesteld op 'Variable Set' en %WIN te kiezen als de variabele die u wilt monitoren. In totaal is deze video van ongeveer 1 minuut vastgelegd 107 wijzigingen in het huidige venster.

Dit soort toegankelijkheidsgebeurtenissen komen met grote frequentie voor tijdens normale gebruikersinteractie. Stel je dus eens voor wat er gebeurt als een gebruiker maakt meerdere toegankelijkheidsservices mogelijk die verzoeken om hoogfrequente toegankelijkheidsevenementen te worden geactiveerd. Dat is juist - vertraging. Om dit te beperken, kunnen ontwikkelaars nauwkeuriger definiëren welke soorten toegankelijkheidsgebeurtenissen ze willen Dienst moet reageren op en in welke context, zoals de mogelijkheid om de Dienst te beperken tot alleen maar reageren wanneer binnen bepaalde apps of om de verkiezingsperiode tussen evenementen. Maar daarnaast is de hoeveelheid overhead die door een toegankelijkheidsdienst wordt gegenereerd grotendeels afhankelijk van welke soorten toegankelijkheidsevenementen het abonneert zich op. In wezen zal niet elke toegankelijkheidsservice vertraging veroorzaken. Eén enkele Toegankelijkheidsdienst die een gebeurtenis met een hoge frequentie vereist, kan vertraging veroorzaken, vooral als deze plaatsvindt genoemde Dienst is gekoppeld aan een andere Dienst waarvoor een ander hoogfrequent Evenement vereist is gecontroleerd.


Duik diep in toegankelijkheid met APK Teardowns

Zoals u uit de hierboven geplaatste video kunt zien, kan een toegankelijkheidsservice die controleert op wijzigingen in de vensterinhoud dat wel resulteren in redelijk merkbare veranderingen in de prestaties van de gebruikersinterface vanwege de enorme hoeveelheid vastgelegde toegankelijkheidsgebeurtenissen die door de systeem. Het is echter vrij lastig om precies te bepalen hoeveel overhead wordt veroorzaakt door een bepaalde toegankelijkheidsdienst. Het monitoren van LogCat levert doorgaans niets op, omdat toegankelijkheidsgebeurtenissen alleen naar LogCat worden afgedrukt als de ontwikkelaar van de toegankelijkheidsservice ervoor kiest dit te doen. Gelukkig is de vader van alle Android-toegankelijkheidsservices, Automatische invoer, doet precies dat. En de LogCat-uitvoer is precies zo rommelig als je zou denken.

AutoInput verbergt de waarheid niet voor ons. De overhead veroorzaakt door de app kan behoorlijk enorm zijn, afhankelijk van welke gebeurtenissen u monitort. Maar deze overhead is nodig om de app te laten functioneren. Om ervoor te zorgen dat AutoInput elke toetsaanslag, elk schermgebaar, elke UI-update en elke druk op een knop onderschept, behoeften om de respectieve toegankelijkheidsgebeurtenissen te monitoren. Zonder deze gebeurtenissen kan AutoInput niet in het systeem aansluiten en de vrijwel onbeperkte UI-automatisering bieden die het momenteel mogelijk maakt. Alle functies van AutoInput zijn dus volkomen logisch binnen de context van toegankelijkheid. Maar voor andere apps moeten we wat dieper kijken om te begrijpen hoe hun toegankelijkheidsservices worden afgehandeld.

Een toegankelijkheidsservice attributen zijn gedefinieerd in een XML-bronbestand binnen de APK. Daarom kunnen we een APK-demontage op een app met een toegankelijkheidsservice om de kenmerken van de service te achterhalen. Elke app functioneert anders, dus ik zal proberen uit te leggen hoe de kenmerken van hun service verband houden met de specifieke functie die deze uitvoert.

Inheems klembord

Native Clipboard is mijn favoriet als het gaat om klembordmanagers. Als u op zoek bent naar een zeer aanpasbare klembordmanager, is Native Clipboard een behoorlijk geweldige app. Het heeft zelfs een Xposed Module-component waarmee u lang op de knop 'Plakken' kunt drukken om de klembordmanager te openen! Helaas, als je geen toegang hebt tot het Xposed Framework (zoals elke gebruiker op Nougat), zul je genoegen moeten nemen voor het inschakelen van de Toegankelijkheidsservice waarmee u op elke tekstinvoer kunt dubbeltikken om het klembord te openen manager. Dit is wat dat inhoudt.


"@string/access_decs"
android: accessibilityEventTypes="typeViewClicked|typeViewFocused|typeViewLongClicked|typeWindowStateChanged"
android: accessibilityFeedbackType="feedbackGeneric"
android: notificationTimeout="100"
android: accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows"
android: canRetrieveWindowContent="true"
xmlns: andro />

De Accessibility Service-verzoeken van Native Clipboard activeren een toegankelijkheidsgebeurtenis elke keer dat er op een weergave wordt geklikt, lang wordt geklikt, de focus wordt gelegd of als er een verandering in de vensterstatus optreedt. Zonder toegang tot de broncode kan ik niet precies zeggen hoe Native Clipboard werkt, maar het is waarschijnlijk dat Native Clipboard wacht tot de vensterstatus aangeeft dat het softtoetsenbord momenteel geopend is, en controleert vervolgens of er op de invoer wordt getikt veld. De app heeft een pollingperiode van 100 ms, dus dat is zeker snel genoeg om in principe onmiddellijk te reageren op veranderingen in de zichtbaarheid van het zachte toetsenbord en op dubbele tikken. Dit kan resulteren in enige UI-overhead wanneer de gebruiker het zachte toetsenbord gebruikt om tekst te typen, wat mogelijk tot vertraging kan leiden.

Vergroenen

Het volgende is ieders favoriete batterijbesparing, Greenify. Greenify gebruikt toegankelijkheidsgebeurtenissen om zijn niet-rootfuncties aan te drijven.


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

Het maakt gebruik van veranderingen in de vensterstatus om te bepalen wanneer het scherm van de telefoon is uitgeschakeld, en vereist dat u de activering van het vergrendelscherm uitstelt door een optie in de beveiligingsinstellingen te wijzigen. Greenify ontvangt ook gebeurtenissen van het type Aankondiging of Meldingsstatus gewijzigd, dit laatste is niet nodig op Android 5.0+ apparaten dankzij de functie Meldingstoegang. Het zal deze gebeurtenissen echter nog steeds ontvangen, ongeacht dat feit. Greenify hoeft op zichzelf niet veel overhead te veroorzaken, maar de mogelijkheid blijft bestaan.

Nova-lanceerder

Waarschijnlijk de meest populaire launcher-app van derden op de markt, Nova Launcher is een uitstekend voorbeeld van een app die een toegankelijkheidsservice gebruikt met minimale tot geen overhead. De enige reden voor het bestaan ​​van de Dienst is om bepaalde apparaten te helpen bij het uitvoeren van gebaren.


"@string/accessibility_service_description"
android: accessibilityEventTypes=""
android: packageNames="com.teslacoilsw.launcher"
android: accessibilityFeedbackType=""
android: notificationTimeout="10000"
android: canRetrieveWindowContent="false"
xmlns: andro />

Zoals u kunt zien, is er geen toegankelijkheidsgebeurtenis gedefinieerd in het XML-bestand. Het enige dat wordt vermeld is de naam van een pakket: Nova Launcher. Wat hier gebeurt, is een oplossing voor bepaalde apparaten waarvoor de gebaren van Nova Launcher niet werken. Deze service biedt Nova Launcher alle toegankelijkheidsevenementen waarmee wordt gestart alleen binnen Nova Launcher. Het klinkt vreemd, maar het is blijkbaar een manier om Nova's startschermgebaren te repareren als je apparaat er niet mee werkt. Omdat deze alleen Evenementen bij Nova zelf opvraagt, brengt de Dienst weinig overhead met zich mee.

LastPass

Tenslotte misschien wel de meest beruchte toegankelijkheidsservice die vertraging veroorzaakt (waarschijnlijk vanwege zijn immense populariteit) - LastPass. Het probleem van vertraging binnen LastPass is zo merkbaar dat het bedrijf een ambtenaar heeft Pagina met veelgestelde vragen waarin het probleem wordt beschreven. Zoals in de FAQ staat, kunt u niets aan de vertraging doen, behalve de service uitschakelen. Waarom lijkt de service van LastPass zo flagrant als het gaat om vertraging? Laten we eens kijken naar de kenmerken van de service.


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

De waarheid is dat er niets bijzonders is aan de service van LastPass. Er worden slechts twee gebeurtenistypen gevraagd om te monitoren: TYPE_VIEW_FOCUSED en TYPE_WINDOW_CONTENT_CHANGED. Het doet dit omdat het moet weten wanneer de inhoud van een app/webpagina verandert/in beeld komt, en vervolgens de huidige vensterinhoud ophaalt om te zoeken naar wachtwoordinvoervelden. Maar omdat de service dit voortdurend doet bij twee extreem frequent geactiveerde toegankelijkheidsgebeurtenissen, resulteert dit in vertraging. Dat is de ongelukkige waarheid.


Leven met de vertraging

Toen we voor het eerst lazen dat Google bugrapporten over toegankelijkheidsvertraging sloot omdat de functie "werkte zoals bedoeld", waren we net zo perplex en boos als velen van jullie. Maar in plaats van de verklaring op het eerste gezicht te aanvaarden, besloten we de zaak zelf te onderzoeken om de waarheid vast te stellen. Dus toen de Googler op de bugrapportpagina dit zei:

Hallo, dit probleem blijft bestaan ​​bij Android-releases. Er zal ook altijd een extra vertraging optreden wanneer een toegankelijkheidsservice is ingeschakeld. Dat komt omdat het apparaat, naast de standaardgebruikersinterface, veel informatie levert aan toegankelijkheidsdiensten, zodat ze die gebruikers een alternatieve gebruikerservaring kunnen bieden.

Wij zijn het gaan begrijpen Waarom dit is bedoeld gedrag. Apps die toegankelijkheidsservices gebruiken op een manier die niet door Google is bedoeld, zullen altijd enige prestatieoverhead met zich meebrengen; deze kosten zijn eenvoudigweg noodzakelijk om Services te voorzien van de overvloed aan informatie die Android Accessibility op de achtergrond afvuurt. De achterstand van Android met toegankelijkheidsservices is dat wel geen bug, maar een feature. Een functie waar we mee zullen moeten leven tenzij het hele systeem wordt herwerkt, en ik kan me niet voorstellen hoe dat zou moeten gebeuren om zoveel verschillende functiesets van zoveel verschillende apps te kunnen huisvesten.

Op zijn minst zouden de LastPass-ontwikkelaars dit niet accepteren. Hun ontwikkelaars hebben samengewerkt met de Chromium-ontwikkelaars toegankelijkheidsondersteuning optimaliseren, misschien door LastPass-ondersteuning in te schakelen door het gebruik van API's in plaats van een toegankelijkheidsservice in te schakelen. Het optimaliseren van de overhead van Accessibility Services is één mogelijkheid, maar zoals veel ontwikkelaars impliciet hebben opgemerkt op de Chromium-forums is het slechts een pleister die het feit niet oplost dat onbedoeld gebruik van toegankelijkheidsservices kan resulteren in vertraging.


Speciale dank aan de ontwikkelaar van AutoInput, joaomgcd, voor het beantwoorden van veel van mijn vragen over toegankelijkheid!