12

For various reasons, I need to runOnUiThread() the actual instantiation & initialization of WebView.

Which means that its underlying HTTP connections are also made on the UI thread?

If this is true, is it possible to separate the WebView's UI thead from the HTTP connections thread?

If it is possible, what is the proper way of accomplishing this?

Bill The Ape
  • 3,261
  • 25
  • 44

1 Answers1

13

I find it very hard to believe that Android would run remote HTTP requests on the UI thread, assuming you initiate the requests via WebView.loadUrl(). This would make for a terrible user experience.

Just quickly, I ran an Android app in the debugger, with a basic WebView, and stopped in the debugger. Here's what I see:

enter image description here

If WebViewCoreThread, WebViewWorkerThread, or http0 - http3 aren't handling the network connections for WebView objects, then

  1. They have very bad names
  2. Android is built really badly

Also, if you look at this answer by one of stack overflow's highest reputation users, loadUrl() is asynchronous. A quick step through in the debugger tells me that loadUrl(), which is called on the UI thread (aka main), completes way too fast for the connection to be handled synchronously on the UI thread. (I put a breakpoint before and after the call to loadUrl() with a URL that I know isn't served very quickly).

So, my answer is you're done ... they're already separate! (yeah!)

Community
  • 1
  • 1
Nate
  • 31,017
  • 13
  • 83
  • 207
  • What you are saying makes sense but in my overridden loadUrl() I actually log the thread id (using `android.os.Process.myTid()`) and it is **exactly the same thread id as the UI's**. Am I missing something? Are you saying that the actual HTTP requests are made on the threads named `http0` - `http3`? Is there a way *for me* to log the actual thread ids in application for these HTTP threads? Thanks. – Bill The Ape Jun 29 '12 at 16:13
  • @BillTheApe, you are correct. `loadUrl()` is called on the UI thread. That's expected. But, what happens (most likely) is that inside Android's implementation of `loadUrl()`, it takes the URL (a `String` or a `URL` object) and puts it into a thread-safe queue. As soon as that's done, `loadUrl()` completes, and returns control to the calling thread (e.g. the UI thread). Then, another thread (not the UI thread) comes through and retrieves the URL from the thread-safe queue and uses it to open a connection to the webserver. It then retrieves the data, and finally ... – Nate Jun 29 '12 at 21:38
  • ... notifies the UI thread to render the retrieved content in the `WebView`. I don't know that this is **exactly** how it works, but that's an example whereby the network activity is handled on a non-UI thread, but your experiment still shows that `loadUrl()` is called on the UI thread. The key is that by the time `loadUrl()` completes, the `WebView` probably doesn't have all the content actually rendered to the screen (or even retrieved from the network). Does that make sense? – Nate Jun 29 '12 at 21:40
  • So, to summarize, think of `loadUrl()` conceptually as a request to **start** a network operation. Not something that completely contains all the work to retrieve and display the data by the time it finishes. – Nate Jun 29 '12 at 21:42
  • 1
    @BillTheApe, for a related issue, [see this other answer I just gave on Android web requests and threading](http://stackoverflow.com/a/11278151/119114). It should clarify what exactly the Android engineers are trying to achieve with their implementation. – Nate Jun 30 '12 at 22:47