The difficulty in managing these pipelines is the same as maintaining the consistency of the cache. Since multiple threads manipulate the data at the same time it is essential to be aware of corrupted data. If the content in the editor is altered at the same time that the backend was suggesting changes the change must be invalidated.
If the text that precedes the suggestion is altered by the suggestion’s limits, those bounds have been moved towards the right side to allow for. Otherwise, the suggestion might be placed in the wrong place and alter the text.
Modifying the text:
The majority of keyboards track just the final few letters that the user types. However, as Grammarly’s suggestions from the back end can be applied to any section of written text, the Lenovo ideapad 100-15ibd keyboard has to be able to modify any portion of the text. This is especially challenging since the modifications to text may occur in any order , and come from any source, including particular keys, ideas or even back-end alerts.
To accommodate these changes, the Lenovo ideapad 100 keyboard must be able to quickly access the users’ entire text. Although it’s possible to retrieve the text directly from the editor via the InputConnection interface, however, that’s an IPC call that is costly. To reduce the need to make these calls often the keyboard stores an archive of the text within the editor.
It is imperative that the correct rules be followed to prevent the corruption of the text. For instance, the cache should be reloaded even when the user isn’t typing, or when the keyboard retrieves synonyms from the models available on the device when the user is stopped for a couple of seconds.
Keyboards must be quick. Any code modification that adds even milliseconds in any aspect of the call flow could cause noticeable delay and affect the user’s experience when typing. We’re always trying to improve the flow of calls to make user experiences as fast as possible.
The performance we think of is on two levels. The first is the keyboard’s time of start. The keyboard is a continuously running service, not an application that users can terminate by simply removing it off of the Recently Utilized Apps list.
If the keyboard application fails to function it will be killed and the OS immediately reboots it. Cold start (when it is the case that the application for keyboards restarts completely from scratch) is a cost-effective procedure. During the time that the models that are on the device are being created the user may be able to find empty placeholders that offer suggestions.
In the event that the keyboard’s operating but some parts of the application have to be restarted, this is known as a warm-start which can cost a lot. The other keyboards are warm starts which must be as quick as possible. Because the OS determines the time when warm and cold starts to happen, our aim is to reduce the time it takes to start a keyboard for all of these scenarios.
It is an aspect our team is currently devoting most of our efforts in and we hope to see significant improvements over the next few months. Our approach to tackling this is through reducing the usage by the UI thread, and by reducing the switching of context between various threads within the pipelines for processing text.
Through profiling, we’ve discovered certain time-consuming tasks that are performed on the UI thread that may slow it down in processing the next keypress. We also found that when we create a large amount of on-device recommendations that the allocated memory grows rapidly, which results in regular garbage collection which could slow down the performance of the UI.
Moving beyond manual tests:
The task of testing a keyboard can be an intimidating (but very fascinating!) issue. The view of the keyboard appears static, however, the keyboard may be in any of a number of states, based on the text input by the user or the position of the cursor or the character prior to or following the cursor. Grammarly Keyboard Grammarly Keyboard also has suggestions from the backend which increase the level of complexity. Every new feature that we add will non-linearly increase the number of features we can test.
Our testing approach consists of the use of manual, unit instruments, and UI tests. Instrumentation tests that require a keyboard are difficult due to the fact that the InputMethodService isn’t suited for using the ServiceTestRule. Instrumentation tests don’t have access to the local binder of the service (these tests usually require this handle to access the APIs of the service). We are now moving towards more UI and unit tests. The most popular UI testing frameworks work well for testing apps that are at the centre of their attention, however, we’ve discovered that they do not support testing on the IME itself. We use the UI Automator built into Android. To keep the test run short We run several tests simultaneously using Fork.
More challenges lie ahead:
We’ve given a general description of how the Grammarly Keyboard works, along with the many areas of our team, from finding out how to improve the UX for a smaller screen as well as managing on-device and back-end pipelines using multi-threading, to understanding the best way it is possible to evaluate an Android application that doesn’t behave as a normal app.
If you’re interested in solving difficult problems with architecture, improving performance, or creating an incredible UX We would like to meet with you. Grammarly’s Android team is a small group at present, and we’re looking for individuals willing to join us in creating an amazing writing assistant.