【问题标题】:Why is my Service stopping?为什么我的服务停止?
【发布时间】:2015-01-17 15:32:23
【问题描述】:

我想知道必须满足什么条件才能让 Android 停止 Service,除了明显的内存不足。

看,我运行一个引导程序 Service,持有一个本地 BroadcastReceiver。该服务本身包含一个状态机,因此我从一个引导状态转换到另一个。每个状态转换函数都会启动AsyncTaskIntentService,一旦完成,它会将Intent 分派回Service,让它知道任务已成功执行。然而,在此期间,服务只是停止,因此意图被派发到空无一物,这令人沮丧。

我不想使用前台服务,也不想为了让我的服务保持活力而欺骗。我也不想依赖onHandleIntent()IntentService,因为IntentService 失去了它的所有状态,这意味着一旦运行所有成员都会被清空,所以当 stateA 完成并且 stateB 应该被启动时,整个状态机为空,所有以前的状态都消失了,等等......

我将Services 上下文提交给每个IntentService/AsnycTask,我认为,只要它们持有服务上下文的引用,Service 就不会停止。可悲的是,事实并非如此......

我是否必须在 doInBackground()AsyncTask 时调用上下文中的方法,以保持 Service 活着或其他什么?

【问题讨论】:

    标签: android service android-context


    【解决方案1】:

    除了系统内存不足之外,如果您的服务超过一定数量的内存,您可能会杀死您的进程(check limitations)。

    与服务进程一样,前台进程可以延长服务的生命周期,但您也无法保证。

    我认为你最好的方法是制定一个与 START_STICKY 模式下的服务一起使用的逻辑 (link)。

    【讨论】:

    • 在这里调试 2gb ram Nexus 5,这不是资源问题。
    • 虽然我知道每个进程都有有限的资源,是的……不过,没有什么特别繁重的事情发生。发出小型 json 请求,检索小型 json 结果。发送数据短信,接收 gcm 通知之类的东西
    【解决方案2】:

    我想知道除了明显的内存不足之外,Android 必须满足哪些条件才能停止服务。

    用户可以随时出于任何原因停止服务,方法是直接停止单个服务,或者(更有可能)终止整个进程。

    如果服务崩溃,Android 会单独停止服务。更常见的是,它终止整个进程以回收该进程的内存以供其他用途。

    我运行一个引导服务,持有一个本地广播接收器

    我怀疑任何人,但你知道在这种情况下“引导”是什么意思。

    每个状态转换函数都会启动一个 AsyncTask 或一个 IntentService,一旦完成,它就会将一个 Intent 分派回 Service,让其知道任务已成功执行。

    使用Service 中的AsyncTask 通常毫无意义。您不想在Service 中的主应用程序线程上做任何事情,AsyncTask 背后的重点是在主应用程序线程上做一些工作(例如,onPostExecute())。使用Thread

    使用Service 中的IntentService 是没有意义且浪费的。你已经有一个Service——它正在做“引导”。你不需要另一个 Service。使用Thread

    但是,在此期间,服务只是停止了,因此意图被派发到空无一物,这令人沮丧。

    更有可能的是,整个过程都消失了。

    我将服务上下文提交给每个 IntentService/AsnycTask

    我并不完全清楚这里的“提交”是什么意思,但如果你将 Context (Service) 传递给另一个 Context (IntentService),那就是严重的代码异味。

    只要他们持有服务上下文的引用,服务就不会停止

    没有。此外,这些都不会阻止 Android 终止您的进程。

    我是否必须在 doInBackground() 一个 AsyncTask 时调用上下文中的方法,只是为了让服务保持活动状态或其他什么?

    不,你需要保持你的状态机持久化(也就是一个文件),这样如果你的进程由于某种原因终止,当你下次再次运行时,你可以从你离开的地方继续。

    【讨论】:

    • 嗨。感谢您的输入,我认为我根本不同意您的 cmets 是因为我提供的关于我所做工作的信息太少,尽管文本已经很长了。 1.) en.wikipedia.org/wiki/Bootstrapping 2.) github.com/android/platform_frameworks_base/blob/master/core/… - 据我所知,AsyncTask 只是 ExecutorService 的包装器。请详细说明为什么使用这个包装器没有意义 3.)整个过程没有走,服务没有在自己的进程中运行,...
    • ...在自动调用 Service.onDestroy() 之后,主要活动仍在运行... 4.) 提交是正确的术语,谢谢。我的解释具有误导性,我使用 Manager-Class 传递上下文。对于不同的事情,我需要这种背景。管理器调用一个执行方法,然后运行 ​​AsyncTask。 onPostExecute() 调用 OnSuccess/Fail 方法,然后分派适当的意图。
    • 5.) 我不需要保持整个状态机持久化。我只需要保持当前状态持久。但是,当我每次调用 onHandleIntent() 时都必须重新初始化它时,状态机毫无意义。我可以直接把它拉出来,然后对收到的意图做出额外的反应......
    • @JohnSmith:“请详细说明为什么使用这个包装器毫无意义”——如果你想要ExecutorService,请使用ExecutorService。实际上,您专门滥用了AsyncTask,让它在您的服务中的主应用程序线程(onPostExecute())上工作,这是不必要的,而且代码有异味。 “在自动调用 Service.onDestroy() 后,主要活动仍在运行”——然后您正在调用 stopService(),您正在调用 stopSelf(),用户正在停止服务,您的服务有未处理的异常,或者你误解了你的调试输出。
    • 对不起,我感觉你是故意误会的。我在后台运行我的背景内容,一旦完成,我评估返回的结果,一个布尔值。如果是真的,我发送一个成功的意图,错误的失败意图。从主线程发送 Intent 没有任何问题。不过你是对的,不需要使用 AsyncTask,我可以使用线程,或者 newSingleThreadExecutor(),是的。这不是重点。但是为了争论,我将用线程替换 AsyncTasks 并看到我的问题没有任何变化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多