„Praca zgodnie z przeznaczeniem”

Wiadomo, że funkcja ułatwień dostępu w Androidzie powoduje opóźnienia interfejsu użytkownika. Czy jest to błąd, czy jest to funkcja? Dlaczego to występuje? W XDA badamy pierwotną przyczynę.

Piękno Androida polega na wielu różnych sposobach interakcji aplikacji innych firm z systemem. Aplikacje do zarządzania hasłami, takie jak LastPass zapewniają możliwość automatycznego podawania odpowiednich danych dotyczących nazwy użytkownika/hasła na prawie każdym ekranie logowania. Pomocnik tekstowy pozwala znacznie skrócić czas wysyłania SMS-ów do znajomych, umożliwiając tworzenie makr rozszerzających tekst. Natywny schowek zmniejsza kłopoty związane z częstym przełączaniem między aplikacjami w celu kopiowania dużych ilości tekstu, umożliwiając dwukrotne dotknięcie dowolnego pola wprowadzania w celu wyświetlenia schowka. Kto może zapomnieć Zazielenianie, być może aplikacja numer 1 wśród entuzjastów, która kontroluje fałszywe aplikacje działające w tle i może w ten sposób wydłużyć czas pracy baterii? Wreszcie, choć mniej zaznajomiony z większością użytkowników, istnieje

Automatyczne wprowadzanie - wtyczka Tasker zaprojektowana do automatyzacji dotknięć ekranu, wprowadzania tekstu, gestów przesuwania i wielu innych. Wszystkie te aplikacje służą do bardzo różnych zastosowań, ale każda z nich opiera się na bardzo źle zrozumianej części podstawowej funkcjonalności Androida: Dostępność.

Przeciętnemu użytkownikowi Androida może wydawać się dziwne, że wiele z tych niesamowitych funkcji używanych przez Twoją ulubioną aplikację jest kontrolowanych za pomocą ustawienia w menu dostępność podmenu. Tworzenie aplikacji dostępny zazwyczaj oznacza, że ​​z aplikacji na Androida może korzystać osoba posiadająca niepełnosprawności. Dlaczego więc LastPass, Native Clipboard, Text Aide, Greenify lub AutoInput mają dostępność praca? Co więcej, dlaczego wydaje się, że włączenie usługi dostępności jest możliwe powodować tak duże opóźnienie interfejsu użytkownika? Wydaje się, że nie ma znaczenia, z której wersji Androida korzystasz – niezależnie od tego, czy jest to wersja Androida 5.0 Lollipop Lub Androida 7.0 Nougat - ponieważ opóźnienie spowodowane niektórymi usługami dostępności może mieć wpływ na Twoje wrażenia. Prostym rozwiązaniem tego problemu jest po prostu wyłączenie usług ułatwień dostępu, które mogłeś włączyć – ale robiąc to, tracimy wiele przydatnych funkcji. Innym rozwiązaniem jest złożenie petycji do Google o „naprawienie” opóźnienia w dostępności Androida, ale Google twierdzi, że w przypadku dostępności Androida tak działa zgodnie z przeznaczeniem. Rozmawialiśmy z kilkoma programistami dobrze zaznajomionymi z usługami dostępności i sprawdziliśmy, jak działa ta funkcjonalność, i jesteśmy tutaj, aby przetestować to twierdzenie: czy opóźnienie dostępności Androida to błąd, czy jest to funkcja?


Zrozumienie dostępności Androida

Jak można sobie wyobrazić po nazwie, dostępność jest przeznaczona głównie dla programistów, aby zapewnić dodatkowe funkcje użytkownikom niepełnosprawnym. Rzeczywiście, szybki rzut oka na oficjalne strony dokumentacji dotyczące ułatwień dostępu pokazuje, że Google ma dość wąski pogląd na to, jakie rodzaje usług powinny być świadczone w ramach usług ułatwień dostępu.

Wielu użytkowników Androida ma różne możliwości, które wymagają od nich interakcji z urządzeniami z Androidem na różne sposoby. Należą do nich użytkownicy, którzy mają ograniczenia wizualne, fizyczne lub związane z wiekiem, które uniemożliwiają im pełne widzenie lub korzystających z ekranu dotykowego oraz użytkowników z ubytkiem słuchu, którzy mogą nie być w stanie dostrzec informacji i ostrzeżeń dźwiękowych.

Android zapewnia funkcje i usługi ułatwień dostępu, które pomagają tym użytkownikom lepiej poruszać się po urządzeniach łatwo, w tym zamianę tekstu na mowę, dotykowe informacje zwrotne, nawigację gestami, trackball i pad kierunkowy nawigacja.

Google'a TalkBack, który jest preinstalowany na każdym telefonie z Androidem, jest doskonałym przykładem tego, jak powinna wyglądać „typowa” usługa ułatwień dostępu. Dostęp głosowy idzie o krok dalej w zakresie dostępności i pozwala na niemal pełną kontrolę nad telefonem za pomocą wyłącznie głosu. Jednak fakt, że Google zamierzył, aby Usługi ułatwień dostępu były wykorzystywane w ten sposób, nie stoi na przeszkodzie programistom możliwość wdrażania ich w dowolny sposób - i właśnie to mają programiści zrobione. Właśnie ze względu na sposób działania ułatwień dostępu powstaje ta funkcja niezwykle przydatne dla użytkowników niepełnosprawnych i pełnosprawnych.

Aby nieco uprościć sprawę, oto podstawowe podsumowanie działania ułatwień dostępu w Androidzie. Deweloper tworzy Usługa dostępności który subskrybuje różne Wydarzenia dotyczące dostępności które są wysyłane przez system do Serwisu w zależności od spełnienia lub nie spełnienia określonych kryteriów. Gdy wszystkie usługi są wyłączone w obszarze Ustawienia -> Dostępność, system Android nie zbiera ani nie wysyła żadnych zdarzeń dostępności. Kiedy jednak użytkownik zacznie włączać usługi ułatwień dostępu, system Android rozpocznie monitorowanie i zbieranie danych tylko te zdarzenia dostępności, o które prosi usługa ułatwień dostępu. Na przykład usługa ułatwień dostępu subskrybująca zdarzenie dostępności TYPE_WINDOW_CONTENT_CHANGED zostanie powiadomiony przez system za każdym razem że nastąpi zmiana w bieżącym oknie. Kolejne wydarzenie dotyczące dostępności tzw TYPE_VIEW_CLICKED odpala za każdym razem użytkownik klika jakiś przycisk.

Demonstracja dostępności Androida. W tym filmie włączyłem aplikację Zadanie monitorować zmiany w tytule okna. Wymaga to włączenia usługi dostępności Taskera. Możesz to powtórzyć, tworząc nowy profil w Taskerze z kontekstem „Zdarzenie” ustawionym na „Zestaw zmiennych” i wybierając %WIN jako zmienną do monitorowania. W sumie nagrano około 1-minutowy film 107 zmian w bieżącym Oknie.

Tego rodzaju zdarzenia związane z dostępnością występują z dużą częstotliwością podczas normalnej interakcji użytkownika. Wyobraź sobie więc, co się stanie, gdy użytkownik umożliwia korzystanie z wielu usług ułatwień dostępu które żądają uruchomienia zdarzeń dostępności o wysokiej częstotliwości. Zgadza się - opóźnienie. Aby temu zaradzić, programiści mogą węższy zdefiniować, jakie rodzaje zdarzeń dostępności mają Serwis powinien reagować i w jakim kontekście, np. możliwość ograniczenia Serwisu tak, aby tylko reagował kiedy w niektóre aplikacje lub ograniczyć okres głosowania pomiędzy Wydarzeniami. Ale poza tym wysokość kosztów ogólnych generowanych przez usługę dostępności zależy głównie od jakie rodzaje zdarzeń związanych z dostępnością to subskrybuje. Zasadniczo nie każda usługa ułatwień dostępu będzie powodować opóźnienia. Pojedyncza usługa ułatwień dostępu, która wymaga zdarzenia o dużej częstotliwości, może powodować opóźnienia, szczególnie jeśli wspomniana Usługa jest połączona z inną Usługą, która wymaga wystąpienia innego Zdarzenia o wysokiej częstotliwości monitorowany.


Zanurz się głęboko w dostępność dzięki porzuceniu APK

Jak można zobaczyć na powyższym filmie, usługa ułatwień dostępu monitorująca zmiany w zawartości okna może powodują dość zauważalne zmiany w wydajności interfejsu użytkownika ze względu na ogromną liczbę przechwyconych zdarzeń dostępności wywołanych przez system. Jednak dość trudno jest dokładnie określić, ile narzutu powoduje konkretna usługa dostępności. Monitorowanie LogCat zazwyczaj do niczego nie prowadzi, ponieważ zdarzenia dostępności są drukowane w LogCat tylko wtedy, gdy twórca usługi dostępności tak zdecyduje. Na szczęście tatuś wszystkich usług ułatwień dostępu w Androidzie, Automatyczne wprowadzanie, robi dokładnie to. Dane wyjściowe LogCat są dokładnie tak niechlujne, jak można sobie wyobrazić.

AutoInput nie ukrywa przed nami prawdy. Narzut powodowany przez aplikację może być dość ogromny, w zależności od monitorowanych zdarzeń. Ale ten narzut jest niezbędny, aby aplikacja działała. Aby funkcja AutoInput przechwytywała każde naciśnięcie klawisza, każdy gest na ekranie, każdą aktualizację interfejsu użytkownika i każde naciśnięcie przycisku, wymagania do monitorowania odpowiednich Zdarzeń Dostępności. Bez tych zdarzeń AutoInput nie może podłączyć się do systemu i zapewnić niemal nieograniczonej automatyzacji interfejsu użytkownika, na jaką obecnie pozwala. Zatem wszystkie funkcje AutoInput mają doskonały sens w kontekście dostępności. Jednak w przypadku innych aplikacji musimy przyjrzeć się nieco głębiej, aby zrozumieć, w jaki sposób obsługiwane są ich usługi ułatwień dostępu.

Usługa dostępności atrybuty są zdefiniowane w Plik zasobów XML w APK. W związku z tym możemy wykonać Porzucenie APK w aplikacji z usługą dostępności, aby poznać atrybuty usługi. Każda aplikacja działa inaczej, dlatego postaram się wyjaśnić, w jaki sposób atrybuty ich Usługi odnoszą się do konkretnej funkcji, którą pełni.

Natywny schowek

Natywny schowek to mój ulubiony program do zarządzania schowkami. Jeśli szukasz wysoce konfigurowalnego menedżera schowka, Native Clipboard to całkiem świetna aplikacja. Zawiera nawet komponent modułu Xposed, który pozwala na długie naciśnięcie przycisku „Wklej”, aby wyświetlić menedżera schowka! Niestety, jeśli nie masz dostępu do Xposed Framework (jak każdy użytkownik Nougata), będziesz musiał się pogodzić za włączenie usługi ułatwień dostępu, która umożliwia dwukrotne dotknięcie dowolnego wprowadzonego tekstu w celu wyświetlenia schowka menedżer. Oto, co to oznacza.


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

Usługa ułatwień dostępu Native Clipboard żąda uruchomienia zdarzenia dostępności za każdym razem, gdy widok zostanie kliknięty, długo kliknięty, aktywny lub gdy nastąpi zmiana stanu okna. Nie mając dostępu do kodu źródłowego, nie mogę dokładnie powiedzieć, jak działa Native Clipboard, ale jest prawdopodobne, że Native Clipboard czeka, aż stan okna wskaże, że klawiatura programowa jest aktualnie otwarta, a następnie monitoruje dotknięcia wejścia pole. Aplikacja ma okres odpytywania wynoszący 100 ms, więc jest to zdecydowanie wystarczająco szybki czas, aby w zasadzie natychmiast zareagować na zmiany widoczności klawiatury programowej, a także podwójne dotknięcia. Może to powodować pewne obciążenie interfejsu użytkownika, gdy użytkownik używa klawiatury programowej do wpisywania dowolnego tekstu, co może skutkować opóźnieniami.

Zazielenianie

Następny w kolejce jest ulubiony przez wszystkich oszczędzacz baterii, Greenify. Greenify wykorzystuje zdarzenia dostępności do obsługi funkcji innych niż root.


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

Wykorzystuje zmiany stanu okna do określenia, kiedy ekran telefonu się wyłączył, i wymaga opóźnienia aktywacji ekranu blokady poprzez zmianę opcji w ustawieniach zabezpieczeń. Greenify będzie także otrzymywać zdarzenia typu Ogłoszenie lub Zmiana stanu powiadomienia, przy czym to drugie jest niepotrzebne na urządzeniach z systemem Android 5.0+ dzięki funkcji Dostęp do powiadomień. Będzie jednak nadal odbierał te wydarzenia niezależnie od tego faktu. Greenify samo w sobie nie powinno powodować dużych kosztów ogólnych, ale istnieje taka możliwość.

Launcher Novy

Prawdopodobnie najpopularniejsza na rynku aplikacja uruchamiająca innej firmy. Nova Launcher jest doskonałym przykładem aplikacji korzystającej z usługi ułatwień dostępu przy minimalnym lub żadnym nakładzie finansowym. Jedynym powodem istnienia Serwisu jest wspomaganie określonych urządzeń w wykonywaniu gestów.


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

Jak widać, w pliku XML nie zdefiniowano żadnego zdarzenia dostępności. Wspomniano tylko nazwę pakietu - Nova Launcher. To, co się tutaj dzieje, jest obejściem dla niektórych urządzeń, na których gesty Nova Launchera nie działają. Ta usługa zapewni Nova Launcher wszystkie zdarzenia dostępności uruchamiane tylko w Nova Launcherze. Brzmi to dziwnie, ale najwyraźniej jest to sposób na naprawienie gestów na ekranie głównym Novy, jeśli Twoje urządzenie z nimi nie współpracuje. Ponieważ wymaga to tylko Wydarzeń od samej Novy, Usługa powoduje bardzo niewielkie obciążenie.

LastPass

Wreszcie, być może najbardziej niesławna usługa dostępności, która powoduje opóźnienia (prawdopodobnie ze względu na jej ogromną popularność) - LastPass. Problemem opóźnienia w LastPass jest tak zauważalne że firma ma urzędnika Strona z często zadawanymi pytaniami opisująca problem. Jak stwierdzono w FAQ, z opóźnieniem nie można zrobić nic poza wyłączeniem Usługi. Dlaczego usługa LastPass wydaje się tak rażąca, jeśli chodzi o opóźnienia? Przyjrzyjmy się atrybutom Usługi.


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

Prawda jest taka, że ​​w usłudze LastPass nie ma nic niezwykłego. Żąda monitorowania tylko dwóch typów zdarzeń - TYPE_VIEW_FOCUSED i TYPE_WINDOW_CONTENT_CHANGED. Robi to, ponieważ musi wiedzieć, kiedy zawartość aplikacji/strony internetowej uległa zmianie/staje się aktywna, a następnie pobiera bieżącą zawartość okna, aby wyszukać pola umożliwiające wprowadzenie hasła. Ponieważ jednak usługa stale robi to w przypadku dwóch niezwykle często uruchamianych zdarzeń dostępności, powoduje to opóźnienia. Taka jest niefortunna prawda.


Życie z lagiem

Kiedy po raz pierwszy przeczytaliśmy, że Google zamyka raporty o błędach związanych z opóźnieniami w dostępności, ponieważ funkcja „działa zgodnie z oczekiwaniami”, byliśmy równie zakłopotani i zdenerwowani, jak wielu z Was. Zamiast jednak przyjąć wyjaśnienia za dobrą monetę, postanowiliśmy sami przyjrzeć się sprawie, aby ustalić prawdę. Kiedy więc Googler na stronie raportu o błędzie powiedział to:

Cześć, ten problem występuje nadal w wersjach Androida. Zawsze będzie występować dodatkowe opóźnienie po włączeniu usługi ułatwień dostępu. Dzieje się tak dlatego, że urządzenie oprócz standardowego interfejsu użytkownika udostępnia wiele informacji usługom ułatwień dostępu, dzięki czemu mogą zapewnić tym użytkownikom alternatywne doświadczenia.

Doszliśmy do zrozumienia Dlaczego to jest zamierzone zachowanie. Aplikacje korzystające z usług ułatwień dostępu w sposób niezamierzony przez Google zawsze będą wiązać się z pewnymi kosztami wydajności; koszt ten jest po prostu niezbędny do zapewnienia Usługom mnóstwa informacji, które funkcja Dostępność systemu Android uruchamia w tle. Opóźnienie Androida w przypadku usług ułatwień dostępu wynosi nie jest to błąd, ale funkcja. Funkcja, z którą będziemy musieli się pogodzić, chyba że cały system zostanie przerobiony. Nie mogę sobie wyobrazić, jak można by to zrobić, aby uwzględnić tak wiele różnych zestawów funkcji z tak wielu różnych aplikacji.

Przynajmniej twórcy LastPass nie pozwoliliby sobie na to. Ich programiści współpracowali z programistami Chromium zoptymalizować obsługę dostępności, być może poprzez włączenie obsługi LastPass poprzez wykorzystanie API zamiast włączać usługę ułatwień dostępu. Optymalizacja pod kątem kosztów ogólnych związanych z usługami dostępności jest jedną z możliwości, ale jak zauważyło wielu programistów na forach Chromium, to po prostu plaster, który nie rozwiąże problemu, że niezamierzone użycie usług ułatwień dostępu może skutkować opóźnienie.


Specjalne podziękowania dla twórcy AutoInput, joaomgcd, za odpowiedź na wiele moich pytań dotyczących dostępności!