-2

这是一个关于 AsyncTask 类的澄清问题以及使用该类进行网络操作(抓取数据)的具体示例。

在 doInBackground 操作之后同步运行的 onPostExecute 方法与让主线程完成所有工作(onPostExecute 和 doInBackground)有何不同?

该主线程将按顺序执行这些操作,获取网络数据,然后在 onPostExecute 中执行工作。

4

3 回答 3

2

文档

当应用程序启动时,系统会为应用程序创建一个执行线程,称为“main”。这个线程非常重要,因为它负责将事件分派给适当的用户界面小部件,包括绘图事件。

换句话说,所有与 UI 相关的任务都发生在同一个线程上,称为主线程或 UI 线程。

当您的应用程序执行密集工作以响应用户交互时,除非您正确实现应用程序,否则这种单线程模型可能会产生较差的性能。具体来说,如果一切都发生在 UI 线程中,那么执行网络访问或数据库查询等长时间操作将阻塞整个 UI。

简而言之,当 UI 必须等待某些 I/O、数据检索或数据处理完成才能完成屏幕渲染时,您的应用程序会“挂起”直到该过程完成。

如果他们不满意,用户可能会决定退出您的应用程序并卸载它。

我认为这是不言自明的。

Android 的单线程模型只有两条规则:

  1. 不要阻塞 UI 线程
  2. 不要从 UI 线程外部访问 Android UI 工具包

因此,与 UI 无关的所有事情都必须在单独的线程中完成,并且与 UI 相关的所有事情都必须没有任何类型的并行处理的情况下完成。

那么我们如何进行并行处理呢?Android 根据您的需求提供不同类型的并行处理:

1.好旧的 JavaThreads

2. Handlers

3. Activity.runOnUiThread(Runnable)

4. View.post(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()

我希望这可以帮到你。

延伸阅读:

1. 了解 AsyncTask——一劳永逸

2 、Android的AsyncTask是串行还是并行执行任务?

于 2014-06-21T07:34:15.130 回答
1

这与效率无关:在主线程中明确禁止网络 I/O (至少,从 Android 3.0 开始)。因此,需要某种方式将这些任务卸载到后台线程中。

AsyncTask只是实现这一点的一种非常方便的机制。

请参阅如何修复 android.os.NetworkOnMainThreadException?

于 2014-06-21T06:34:38.850 回答
0

那很简单。如果你在主线程上下载你的东西,它会阻止你的 UI 并且ANR 对话框会出现。您的 Activity 与 XML 相关联:

 setContentView(R.layout.activity_main);

但是如果你使用 Asynctask 会启动新线程,这与 UI 无关。所以在你开始你的异步任务之后,你仍然可以显示任何你想要的东西,按钮将是可点击的,等等。如果你将它下载到你的主线程上,用户可以认为应用程序冻结并退出,尽管它只是在做一些计算。

于 2014-06-21T06:45:58.873 回答