【问题标题】:Keeping an AsyncTask alive in low memory conditions?在内存不足的情况下保持 AsyncTask 存活?
【发布时间】:2010-08-22 13:56:10
【问题描述】:

我已将主屏幕小部件编写为 ImageView,即。该代码生成整个小部件并将其作为位图写入 RemoteViews。在内存较低的较慢设备上,例如我的 G1,生成位图可能需要几秒钟,为了避免可怕的强制关闭,我将所有图形代码移到 AsyncTask 中。到目前为止一切顺利。

但是,在内存非常低的情况下,AsyncTask 很容易在它完成生成位图之前被操作系统杀死,从而导致主屏幕上出现一个空白方块。所以在创建 AsyncTask 之前,它设置了 now + 5 秒的警报,并且在图形完成后,它会重置警报。这里的假设是,如果触发了警报,则很可能进程已被杀死,我们必须设置另一个 now+5 警报并重新开始。

这确实有效,但在内存极低的情况下,绘制小部件可能需要多次尝试(20 多秒),所以我添加了一个占位符沙漏图像,作为静态资源,它显示在主屏幕上,直到真正的图像已准备就绪。

我的问题是:这是最好的方法吗?有什么方法(礼貌地)要求操作系统在 AsyncTask 完成之前不要杀死它(因为杀死它实际上会导致更多浪费系统资源)?

我知道,如果一个进程被归类为“可见”,那么 Android 不会杀死它,除非是万不得已。但我不知道如何将 AsyncTask 标记为“可见”。我很高兴该过程在绘制小部件后立即被终止。只是希望它能够存活足够长的时间以完成。

【问题讨论】:

    标签: android memory android-widget android-asynctask


    【解决方案1】:

    通过绑定到 EmptyService 并在工作完成后解除绑定来使用它,请参阅https://github.com/android/platform_packages_providers_calendarprovider/blob/master/src/com/android/providers/calendar/EmptyService.java。我不确定这是否能保证您的进程不会被杀死,或者是否只是减少了它被杀死的机会。

    您也可以使用前台服务,但您必须为其提供状态栏通知,请参阅http://developer.android.com/guide/components/services.html#Foreground

    或者您可以按照@Mike 的建议使用 IntentService;虽然我在文档中看不到“它获得与前台任务相同的终止优先级”。

    【讨论】:

      【解决方案2】:

      您是否考虑过为此使用 IntentService?当您的服务代码正在执行时,它会获得与前台任务相同的终止优先级。它不会像 AsyncTask 那样与小部件紧密耦合,但我认为它会增加代码完成的几率。

      【讨论】:

      • 我刚试过,花了几个小时玩不同的设置。我用 START_STICKY、setForeground() 和 WAKE_LOCK 进行了尝试。不幸的是,它们都没有在内存不足的情况下使代码保持活力,也没有像我目前使用的警报代码那样轻松快速地恢复。
      • 我浏览了一些谷歌的 Android 操作系统代码,我注意到当他们使用 AsyncTask 时,他们偶尔会从 AsyncTask 中启动一个空服务,根据 cmets,它是为了保持任务被杀死。您可以在此文件的第 670 行看到对它的引用:android.git.kernel.org/?p=platform/packages/apps/…
      【解决方案3】:

      尝试使用服务类,你可以将服务设置为“前台”。关闭前台服务的可能性几乎为零。

      另外,Service 的作用与 Async 相同。

      一旦你完成工作,然后关闭服务。

      【讨论】:

        猜你喜欢
        • 2012-06-10
        • 2012-01-26
        • 1970-01-01
        • 2023-03-23
        • 2011-09-10
        • 2019-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多