我想确保不会减慢应用的启动时间,并且需要启动与用户输入无关的后台任务 - 例如,填充缓存。
如果我从AsyncTask
方法开始onCreate
,那么doInBackground
方法何时才能真正开始执行? (假设一个核心设备)
Android有可能在onCreate/onResume
完成之前安排它,或者它是否足够智能识别后台线程在UI线程完成之前不应运行?
答案 0 :(得分:1)
如果查看AsyncTask
source code,您会看到它只是使用ThreadPoolExecutor
或串行执行程序来运行任务。默认的内部行为取决于Android版本(来自AsyncTask docs):
首次引入时,AsyncTasks在单个后台线程上串行执行。从DONUT开始,这被改为一个线程池,允许多个任务并行运行。从HONEYCOMB开始,任务在单个线程上执行,以避免由并行执行引起的常见应用程序错误。
但无论如何doInBackground
执行与Activity
生命周期无关,因此AsyncTask
几乎可以在任何时间执行。这取决于您已经启动的任务数量,Executor
和线程调度程序使用的默认AsyncTask
。
答案 1 :(得分:0)
我通常在AsyncTask
中使用onCreate()
,如下所示:
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);
}
}
这可确保在任务开始之前初始化所有内容。
答案 2 :(得分:0)
实际上严格来说,没有UI代码的执行顺序,并启动我发现的asynctask。通常情况下,没有人会遇到这种情况,但是,如果您的UI线程由于某种原因需要更长的时间,例如等待外部输入等,那么在UI代码完成之前,asynctask可能已经开始了。
编写UI代码只是对Android系统的请求,并且在执行循环中等待。因此,如果asynctask在此之前启动,因为有足够的资源(或者提到的UI线程因任何原因而被延迟),则没有执行顺序保证。
执行此操作的一种简单方法是 - 如果您不介意并且您可以确定它是足够的 - 延迟使用ScheduledExecutorService启动asynctask或“更清洁”的方式将实现某种类型的门等待标志设置为true然后启动asynctask的守护者。或者你甚至可以在asynctask的开头有一个while循环,等待标志设置为true,就像许多与外部设备的通信情况一样。
在您(通常)确定您的UI已完成之后,该标志将设置为true。