2012-07-15 44 views
2

我想确保不会减慢应用程序的启动时间,并且需要启动与用户输入无关的后台任务 - 例如填充缓存。如果我在onCreate期间启动一个AsyncTask,它何时开始执行?

如果我从onCreate方法开始AsyncTask方法,doInBackground方法何时会实际开始执行? (假设有一个核心设备)

Android可能在onCreate/onResume完成之前安排它,或者足够聪明地认识到后台线程在UI线程完全结束之前不应运行?

回答

1

如果你看看AsyncTasksource code你会发现它只是使用ThreadPoolExecutor或串行执行程序来运行任务。缺省的内部特性取决于Android版本(来自的AsyncTask文档):

当首次引入AsyncTasks物连续在单个后台线程执行。从DONUT开始,将其更改为允许多个任务并行操作的线程池。从HONEYCOMB开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

但无论如何doInBackground执行不与Activity生命周期,从而AsyncTask可以在几乎任何时候来执行连接。这仅取决于您已经开始了多少任务,缺省值Executor(由AsyncTask使用)和线程调度程序。

+0

好点:如果你不向UI发送任何东西,这只适用于doInBackground()方法。通常建议在执行doInBackround()的同时附加一些活动的上下文以显示onPreExecute()或onPostExecute()方法中的任务信息。所以,对于大多数情况,AsyncTask和Activity之间有很强的关系。只有少数情况下,您可以使用它来在用户的用户界面中不显示任何背景任务,并且在这种情况下,只有AsyncTask可以被视为与活动分离。 – 2012-07-17 03:16:08

0

我通常在onCreate()使用AsyncTask就像这样:

private MySuperSpecialTask mySuperSpecialTask; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // setContentView(...); 
    // [...] 

    mySuperSpecialTask = new MySuperSpecialTask(); 
    mySuperSpecialTask.execute(); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    if (mySuperSpecialTask != null) { 
     mySuperSpecialTask.cancel(true); 
    } 
} 

这可以确保任务得到启动之前的一切被初始化。

+0

为什么你的OnCreate方法不是异步无效的?这样做有问题吗? – batmaci 2017-07-05 14:41:47

+0

async void?你知道这是Java而不是C#吗? 编辑:另外,我的答案是从2012年开始,所以它可能已经过时了一段时间了。 – chrulri 2017-07-18 17:19:54

0

实际上严格来说,没有你的UI代码的执行顺序,并开始我发现的asynctask。通常情况下,你不会遇到这种情况,但是,如果你的UI线程由于某种原因需要更长的时间,例如等待外部输入等等,那么asynctask可能已经在UI代码完成之前开始了。

写入UI代码只是一个对Android系统的请求,并在执行循环中等待。因此,如果asynctask在此之前开始,因为有足够的资源(或者由于任何原因延迟提及的UI线程)没有执行顺序保证。

执行此操作的一个简单方法是 - 如果您不介意并且可以确定它足够充足 - 使用ScheduledExecutorService或更简洁的方式延迟asynctask的启动将实现某种守门员等待一个标志设置为真,然后启动asynctask。或者你甚至可能在你的异步开始时有一个while循环,等待标志被设置为真,就像在许多外部设备的通信情况下一样。

该标志将设置为true后,您可以(通常)确保您的用户界面已完成。

相关问题