为什么不在主线程(Android)中执行所有操作?

时间:2014-06-21 06:32:51

标签: java android multithreading android-asynctask clarity

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

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

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

3 个答案:

答案 0 :(得分:1)

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

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

请参阅How to fix android.os.NetworkOnMainThreadException?

答案 1 :(得分:1)

来自docs

When an application is launched, the system creates a thread of execution for the application, called "main." This thread is very important because it is in charge of dispatching events to the appropriate user interface widgets, including drawing events.

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

When your app performs intensive work in response to user interaction, this single thread model can yield poor performance unless you implement your application properly. Specifically, if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI.

简单地说,当UI必须等待一些I / O,数据检索或数据处理才能完成呈现屏幕之前,您的应用程序会挂起"直到那个过程完成。

The user might then decide to quit your application and uninstall it if they are unhappy.

我认为这是不言自明的。

There are simply two rules to Android's single thread model:

1. Do not block the UI thread

2. Do not access the Android UI toolkit from outside the UI thread

因此,与UI 必须无关的所有内容都可以在一个单独的主题中完成,并且与必须相关的所有内容都可以完成没有任何类型的并行处理。

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

1。 Good old Java Threads

2。 Handlers

3。 Activity.runOnUiThread(Runnable)

4。 View.post(Runnable)

5. View.postDelayed(Runnable, long)

6。 AsyncTasks

7。 IntentServicesServices 不要在单独的线程上运行。)

另外,Android会明确强制所有网络操作都在一个单独的线程上执行,否则会引发NetworkOnMainThreadException

现在回到你的问题:My question is how is this difference form just running everything on the main thread? I know that onPostExecute has to wait for the xml do in background retrieve to finish which will still lock up the ui for the user?

如果设备有多个核心,则UI渲染通过一个核心(主线程)完成,而doInBackground()方法在另一个核心(AsyncTask线程上执行),只有在onPostExecute()返回后,才会在主线程上调用doInBackground()方法。这意味着onPostExecute()也在等待UI完成渲染,因为UI渲染和onPostExecute()出现在主线程上。

现在,如果设备只有一个核心,一切都将在一个核心上发生,但doInBackground()将在一个单独的线程上执行,只有在UI渲染完成后才会调用onPostExecute() doInBackground()已退回。

我希望这很有帮助。

进一步阅读:

1。 Understanding AsyncTask – Once and Forever

2。 Is Android’s AsyncTask executing tasks serially or concurrently?

答案 2 :(得分:0)

这很简单。如果您在主线程上下载内容,它将阻止您的用户界面并显示ANR dialog。您的Activites与XML绑定:

 setContentView(R.layout.activity_main);

但是如果你使用Asynctask,将启动新的线程,这与UI无关。因此,在启动Asynctask之后,您仍然可以显示任何您想要的内容,按钮可以点击等等。如果您要在主线程上下载它,用户可以认为应用程序冻结并退出,只是它只是在进行一些计算。 / p>