这是一个关于 AsyncTask 类的澄清问题以及使用该类进行网络操作(抓取数据)的具体示例。
在 doInBackground 操作之后同步运行的 onPostExecute 方法与让主线程完成所有工作(onPostExecute 和 doInBackground)有何不同?
该主线程将按顺序执行这些操作,获取网络数据,然后在 onPostExecute 中执行工作。
这是一个关于 AsyncTask 类的澄清问题以及使用该类进行网络操作(抓取数据)的具体示例。
在 doInBackground 操作之后同步运行的 onPostExecute 方法与让主线程完成所有工作(onPostExecute 和 doInBackground)有何不同?
该主线程将按顺序执行这些操作,获取网络数据,然后在 onPostExecute 中执行工作。
从文档:
当应用程序启动时,系统会为应用程序创建一个执行线程,称为“main”。这个线程非常重要,因为它负责将事件分派给适当的用户界面小部件,包括绘图事件。
换句话说,所有与 UI 相关的任务都发生在同一个线程上,称为主线程或 UI 线程。
当您的应用程序执行密集工作以响应用户交互时,除非您正确实现应用程序,否则这种单线程模型可能会产生较差的性能。具体来说,如果一切都发生在 UI 线程中,那么执行网络访问或数据库查询等长时间操作将阻塞整个 UI。
简而言之,当 UI 必须等待某些 I/O、数据检索或数据处理完成才能完成屏幕渲染时,您的应用程序会“挂起”直到该过程完成。
如果他们不满意,用户可能会决定退出您的应用程序并卸载它。
我认为这是不言自明的。
Android 的单线程模型只有两条规则:
- 不要阻塞 UI 线程
- 不要从 UI 线程外部访问 Android UI 工具包
因此,与 UI 无关的所有事情都必须在单独的线程中完成,并且与 UI 相关的所有事情都必须在没有任何类型的并行处理的情况下完成。
那么我们如何进行并行处理呢?Android 根据您的需求提供不同类型的并行处理:
1.好旧的 JavaThreads
2. Handlers
3. Activity.runOnUiThread(Runnable)
5. View.postDelayed(Runnable, long)
6. AsyncTasks
7. IntentServices
(不要在单独的线程上运行)。Services
附带说明一下,Android 特别强制所有网络操作都在单独的线程上执行,否则NetworkOnMainThreadException
会抛出 a 。
现在回到你的问题:
我的问题是这种差异形式如何仅在主线程上运行所有内容?我知道 onPostExecute 必须等待后台检索中的 xml 完成,这仍然会为用户锁定 ui?
发生的情况是,如果设备有多个内核,则 UI 渲染通过一个内核(主线程)完成,而doInBackground()
方法在另一个内核(AsyncTask
线程)上执行,并且onPostExecute()
只有在主线程上调用该方法doInBackground()
已经回来了。这意味着它onPostExecute()
也在等待 UI 完成渲染,因为 UI 渲染和都onPostExecute()
发生在主线程上。
现在如果设备只有一个核心,那么一切都将发生在一个核心上,但doInBackground()
会在单独的线程上执行,并且只有在 UI 渲染完成并返回onPostExecute()
后才会被调用。doInBackground()
我希望这可以帮到你。
延伸阅读:
这与效率无关:在主线程中明确禁止网络 I/O (至少,从 Android 3.0 开始)。因此,需要某种方式将这些任务卸载到后台线程中。
AsyncTask
只是实现这一点的一种非常方便的机制。
那很简单。如果你在主线程上下载你的东西,它会阻止你的 UI 并且ANR 对话框会出现。您的 Activity 与 XML 相关联:
setContentView(R.layout.activity_main);
但是如果你使用 Asynctask 会启动新线程,这与 UI 无关。所以在你开始你的异步任务之后,你仍然可以显示任何你想要的东西,按钮将是可点击的,等等。如果你将它下载到你的主线程上,用户可以认为应用程序冻结并退出,尽管它只是在做一些计算。