Android WebView and the UI thread

This document describes how the Chromium based Android WebView reconciles with mismatching requirements and assumptions between Android and Chromium about the UI thread.

The UI Thread in Chromium

In Chromium, there is a single global UI thread in the browser process. It is one of the explicitly named BrowserThreads. The UI thread is generally where UI code runs, including input delivery from the OS.

The concept of “the one and only UI thread” is well established in content layer and above. For example, all WebContents live on this UI thread.

View Threads in Android

A Window, its view tree, and Views in that tree are all single threaded in general; for a particular View, call this the view thread. It is possible to create separate Windows and view trees on separate threads, as long as Views are not moved between them. So there can be more than one view thread.

Most apps do not make use of this hidden feature; they use a single view tree on the main thread of the application. However, in general, it’s not safe to assume there’s only a single view thread, or that the view thread and the main thread is the same.

Best effort solution

WebView’s solution is use the first view thread as the UI thread, then post non-UI thread calls to the UI thread, and block if needed.

Because Chromium initialization identifies the thread as the UI thread, parts of this solution runs before Chromium is initialized. The implementation is in the android webview glue layer, specifically in WebViewChromium and WebViewChromiumFactoryProvider. The idea is hold off initializing chromium until a view thread is identified.

View thread can be identified by certain View methods. For example, onAttachedToWindow is called by the view tree on the view thread. Of course this is not 100% reliable since apps could call those methods as well.

In case a method that cannot be held off is called before a view thread is identified, the main thread is used as the UI thread. Methods calls that are not held off include:

  • Methods with an immediate output with no meaningful defaults without initialization.
    • onDraw: Need to draw into canvas parameter
    • Any method with a return value, like getHttpAuthUsernamePassword.
  • “Important” calls that should not be held off. This is a judgement call mostly.
    • Currently only loadUrl and loadData family of calls

View is Single-Threaded

Views in android are expected to be created and used on its single view thread, unless otherwise noted in the API. For WebView, this is enforced for apps targeting JB MR2 or above. The code lives in the WebView. Note this is an orthogonal concern to the single UI thread described above, as this check still allows different WebViews to be used on different view threads.