WebView的UI线程和HTTP线程是否可以分离?

12

由于种种原因,我需要在UI线程上运行runOnUiThread()来实际实例化和初始化WebView

这意味着它的底层HTTP连接也是在UI线程上进行的吗?

如果是这样,是否有可能将WebView的UI线程与HTTP连接线程分离?

如果可能,正确的完成方式是什么?

1个回答

13

我觉得很难相信Android会在UI线程上运行远程HTTP请求,假设您通过WebView.loadUrl()发起请求。这会导致可怕的用户体验。

简单地说,我在调试器中运行了一个带有基本WebView的Android应用程序,并停在调试器中。这是我看到的:

enter image description here

如果WebView对象的网络连接不由 WebViewCoreThreadWebViewWorkerThreadhttp0-http3 处理,则

  1. 它们的命名非常糟糕
  2. Android构建得非常糟糕

此外,如果您查看stackoverflow最高声望用户之一的答案loadUrl()是异步的。快速调试告诉我,调用在UI线程(即main)上进行的loadUrl()完成得太快,无法同步处理UI线程上的连接。(我在调用知道响应时间不快速的URL之前和之后设置了断点)。

因此,我的回答是你已经完成了...它们已经是分离的!(耶!)


你说的有道理,但在我的重写loadUrl()方法中,我实际上记录了线程ID(使用android.os.Process.myTid()),它与UI的线程ID完全相同。我错过了什么吗?您是说实际的HTTP请求是在名为http0 - http3的线程上完成的吗?是否有一种方法可以记录这些HTTP线程的实际线程ID?谢谢。 - Bill The Ape
@BillTheApe,你是正确的。loadUrl()在UI线程上调用是预期的。但是,最有可能发生的情况是,在Android的loadUrl()实现内部,它将URL(一个字符串或URL对象)放入线程安全队列中。一旦完成这个操作,loadUrl()就会完成并返回控制权给调用线程(例如UI线程)。然后,另一个线程(不是UI线程)会从线程安全队列中检索URL,并使用它打开到Web服务器的连接。然后它检索数据,最终... - Nate
...通知UI线程在WebView中呈现检索到的内容。我不确定这是否完全是它的工作方式,但这是一个例子,其中网络活动在非UI线程上处理,但您的实验仍然显示loadUrl()在UI线程上调用。关键是在loadUrl()完成时,WebView可能实际上并没有将所有内容呈现到屏幕上(甚至没有从网络中检索到所有内容)。这有意义吗? - Nate
所以,总结一下,从概念上来说,loadUrl()可以被视为发起一个网络操作的请求。它并不完全包含在完成时检索和显示数据的所有工作。 - Nate
1
@BillTheApe,针对你提到的问题,请看我在Android网络请求和线程上刚回答的另一个问题。它应该能够澄清Android工程师们正在尝试实现的目标。 - Nate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接