何时关闭android应用程序中的executorservice

时间:2013-05-01 10:59:52

标签: android executorservice

让我们假设我计划在我的整个应用程序中使用一个executorservice,我正在发送新的runnable或callable来执行/提交,并且我在执行此操作后立即关闭。我只想把我的“任务”扔给executorservice并让他处理它们并执行它们给它的资源(他有多少线程可用,如果需要可以创建多少线程,然后相应地排队这些任务)。

根据您在Android应用程序中使用ExecutorService的经验,并考虑到应用程序状态的变化,如果我不想通过这样做不断关闭并重新创建执行程序服务:

    executor = Executors.newCachedThreadPool();
    executor.submit(some Runnable);
    executor.shutdown();

,您将在什么时间和地点推荐关闭服务,然后恢复它以便我可以防止一些泄漏或一些不可预见的后果?

我大部分时间都在努力:

1)在Backstack中的最后一个活动上通过后退按钮关闭应用程序(应用程序使用许多活动) 2)申请在后台进行(在任何这些活动上) 3)应用程序返回到前台(在任何这些活动上)

3 个答案:

答案 0 :(得分:10)

你可以做一个解决方法。将执行程序创建为守护程序。然后它会在您的应用程序退出时自动结束。您无需明确调用shutdown

 ExecutorService es = Executors.newSingleThreadExecutor( new ThreadFactory() {
    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
});

答案 1 :(得分:4)

我有一个ExecutorService的单例实例,它通过Dagger的对象图限定为Android应用程序实例。 因此,实例与Application对象本身一样长。由于Android的Application类不提供onDestroy()回调,因此在ExecutorService上调用shutdown()时永远不知道。

由于我害怕内存泄漏,我也在调查ThreadPoolExecutor并使用它来查找。这是我发现的:Executors.newCachedThreadPool()使用以下参数创建一个ThreadPoolExecutor:

ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>())

这是一个0的corePoolSize,这意味着最少0个工作线程保持活动状态,因此没有。当TPE(a.k.a ExecutorService)执行任务时,它会创建一个工作线程并将其添加到池中。现在,当60秒超时期间没有新任务进入时,(仍保持活动状态)工作线程终止并从池中移除(缓存)。

对我而言,这意味着即使从未在ExecutorService上调用shutdown()也不会发生内存泄漏,因为所有工作线程都存在,超时并且在没有新任务时将从池中删除在超时期间进来。 我想那样,就不会有任何对工作线程的引用,因此GC可以清理TPE实例。

如果我错了,请随意纠正我。

答案 2 :(得分:0)

尽管这个问题已经发布多年了,但最近 Android API 30 已弃用 AsyncTask,有人可能会卡在这里。为了回答这个问题,没有必要关闭单例 ExecutorService 除非它有任何空闲线程。根据{{​​3}}:

<块引用>

不再在程序中引用并且没有剩余的池 线程将自动 shutdown。如果您想确保 即使用户忘记调用,未引用的池也会被回收 shutdown(),那么你最终必须安排那些未使用的线程 死,通过设置适当的保持活动时间,使用下限 零核心线程...

对于这种情况,Executors.newCachedThreadPool() 是一个很好的工厂方法。当您的应用进程终止时,它会自动关闭。

MyApplication.java:

public class MyApplication extends Application {
    private static ExecutorService executorService = Executors.newCachedThreadPool();
    ...
    public static Executor getExecutor() {
        return executorService;
    }
}

只需在代码中的任何位置使用 MyApplication.getExecutor()