为啥不在主线程(Android)中完成所有操作? [关闭]
Posted
技术标签:
【中文标题】为啥不在主线程(Android)中完成所有操作? [关闭]【英文标题】:Why not do all the operations in the main thread(Android)? [closed]为什么不在主线程(Android)中完成所有操作? [关闭] 【发布时间】:2014-08-11 21:43:09 【问题描述】:这是一个关于 AsyncTask 类的澄清问题,以及使用该类进行网络操作(抓取数据)的具体示例。
在 doInBackground 操作之后同步运行的 onPostExecute 方法与让主线程完成所有工作(onPostExecute 和 doInBackground)有何不同?
该主线程将按顺序执行这些操作,获取网络数据,然后在 onPostExecute 中执行工作。
【问题讨论】:
看看这个 --> vogella.com/tutorials/androidBackgroundProcessing/article.html 这个问题的问题在于它太宽泛,根本没有重点。我无法为此重新打开它,但我可以建议您举一个使用 onPostExecute 方法的具体示例,但您不理解它。抱歉,我无法为您提供更多帮助 @aradhna 感谢您的文章!该文章中的这句话本身回答了这个问题 - “如果您执行长期操作,例如从 Internet 访问数据,应用程序会阻塞,直到相应的操作完成。” 【参考方案1】:来自docs:
当启动应用程序时,系统会为应用程序创建一个执行线程,称为“main”。这个线程非常重要,因为它负责将事件分派给适当的用户界面小部件,包括绘图事件。
也就是说,所有 UI相关的任务都发生在同一个线程上,称为主线程或UI线程。
当您的应用执行大量工作以响应用户交互时,除非您正确实施应用,否则这种单线程模型可能会产生较差的性能。具体来说,如果一切都发生在 UI 线程中,那么执行网络访问或数据库查询等长时间操作将阻塞整个 UI。
简单地说,当 UI 必须等待某些 I/O、数据检索或数据处理完成才能完成屏幕渲染时,您的应用程序会“挂起”直到该过程完成。
如果他们不满意,用户可能会决定退出您的应用程序并卸载它。
我认为这是不言自明的。
Android 的单线程模型只有两条规则:
不要阻塞 UI 线程 不要从 UI 线程外部访问 Android UI 工具包
因此,与 UI 无关的所有内容必须在单独的线程中完成,而与 UI 相关的所有内容必须在没有的情况下完成任何类型的并行处理。
那么我们如何进行并行处理呢? Android 根据您的需要提供不同类型的并行处理:
1. 好旧的 Java Threads
2. Handlers
3. Activity.runOnUiThread(Runnable)
4. View.post(Runnable)
5. View.postDelayed(Runnable, long)
6. AsyncTasks
7. IntentServices
(Services
请勿在单独的线程上运行)。
附带说明,Android 特别强制所有网络操作在单独的线程上执行,否则会抛出 NetworkOnMainThreadException
。
现在回到你的问题:
我的问题是这种差异形式如何仅在主线程上运行所有内容?我知道 onPostExecute 必须等待后台检索中的 xml 完成,这仍会为用户锁定 ui?
如果设备有多个内核,UI 渲染将通过一个内核(主线程)完成,而 doInBackground()
方法在另一个内核(AsyncTask
线程)上执行,并且onPostExecute()
方法仅在 doInBackground()
返回后才在主线程上调用。这意味着 onPostExecute()
也在等待 UI 完成渲染,因为 UI 渲染和 onPostExecute()
都发生在主线程上。
现在如果设备只有一个核心,一切都将发生在一个核心上,但doInBackground()
将在单独的线程上执行,并且onPostExecute()
将仅在 UI 渲染完成并且doInBackground()
完成后调用返回。
我希望这会有所帮助。
进一步阅读:
1. Understanding AsyncTask – Once and Forever
2. Is Android’s AsyncTask executing tasks serially or concurrently?
【讨论】:
对不起,我应该更清楚...术语“核心”是指设备微处理器中的 CPU 数量。过去微处理器是单核的,传统上一个核一次可以执行一条指令,也就是说一个核处理一个线程,上下文切换造成了多任务的错觉.单个处理器中存在多个内核是真正在计算机(现在也包括移动设备!)中实现多任务处理的原因......这有帮助吗? 设备是否有微处理器和主处理器(CPU?) 两者指的是同一个东西【参考方案2】:这与效率无关:网络 I/O 在主线程中明确禁止(至少从 Android 3.0 开始)。因此,有必要通过某种方式将这些任务卸载到后台线程中。
AsyncTask
只是实现这一点的一种非常方便的机制。
见How to fix android.os.NetworkOnMainThreadException?
【讨论】:
【参考方案3】:这很简单。如果你在主线程上下载你的东西,它会阻塞你的 UI 并且ANR dialog 会出现。您的 Activity 与 XML 相关联:
setContentView(R.layout.activity_main);
但是如果你使用 Asynctask 会启动新线程,这与 UI 无关。所以在你开始你的异步任务之后,你仍然可以显示任何你想要的东西,按钮将是可点击的,等等。如果你将它下载到你的主线程上,用户可以认为应用程序冻结并退出,尽管它只是在做一些计算。
【讨论】:
以上是关于为啥不在主线程(Android)中完成所有操作? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 UIWebView 的 AVPlayerViewController 不在主线程上运行?