1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73

android_webview / docs / threading.md [blame]

# 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](/content/public/browser/browser_thread.h).
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](https://developer.android.com/reference/android/view/Window.html),
its view tree, and
[Views](https://developer.android.com/reference/android/view/View) 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](https://developer.android.com/reference/android/os/Looper#getMainLooper())
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](../glue/java/src/com/android/webview/chromium/WebViewChromium.java)
and [WebViewChromiumFactoryProvider](../glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java).
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](https://developer.android.com/reference/android/view/View.html#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
[WebView.java](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/webkit/WebView.java).
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.