Android 个工作线程持续多长时间?

How long do Android worker threads last?

我看过一些关于这个主题的帖子,但是 none 的帖子都有令人满意的答案。

假设我从我的主线程(唯一的)Activity,在它的 onCreate() 方法中启动一个工作线程。然后我调用 finish() 使 Activity 终止。

此时,它所属的任务被销毁(因为其中不再有任何 Activity)。该应用程序(以及进程 运行 它)可能会继续存在,但是,以空的 "skeleton" 形式存在,以便它可以在需要时快速重新启动(尽管它很容易被系统)。

假设以上是正确的——工作线程何时被终止?是系统主动销毁进程才杀掉吗?

在我的例子中,我的工作线程作为蓝牙连接的侦听器存在;收到后,它将再次启动所需的 Activity。在这种情况下,没有活动的 运行 组件(ActivityServiceContentProviderBroadcastReceiver)。在我看来,这应该可行,只是有些东西正在杀死我的工作线程。

我知道我可以通过使用背景 Service 来做到这一点(而且痛苦更小)。但是,我很好奇为什么这不起作用。

谢谢, 巴里

Android中有一个主线程(也称为UI)。这是您的应用程序使用的唯一线程,除非它通过 Thread.start()AsyncTask.execute() 等显式启动一个线程。所有活动、服务、BroadcastReceivers 等 运行 该主线程上的所有生命周期方法.请注意,我在主线程上包含了服务 - 服务 运行s,除非它启动自己的线程(例外情况是 IntentService,它在自己的线程上执行 运行)。

您创建的 Thread 会一直持续到 Runnable 从其 运行 函数传递给 returns 为止(或者进程当然终止)。这可以在创建它的 Activity/Service 结束后继续存在。然而,这样的线程仍然存在于组件的原始实例中,并且如果在没有大量特殊工作的情况下重新启动一个实例,则将无法访问新实例的变量(请参阅加载程序模式)。

Android App lifecycle 有一个非常切合主题的好例子:

A common example of a process life-cycle bug is a BroadcastReceiver that starts a thread when it receives an Intent in its BroadcastReceiver.onReceive() method, and then returns from the function. Once it returns, the system considers the BroadcastReceiver to be no longer active, and thus, its hosting process no longer needed (unless other application components are active in it). So, the system may kill the process at any time to reclaim memory, and in doing so, it terminates the spawned thread running in the process.

简而言之,如果你的线程有机会 运行 直到终止或进程将被提前杀死,它真的不是很可预测,你绝对不应该依赖任何 order/behavior.

值得一提的是,即使您完成了它,也很容易 leak 您的 activity 和线程,但是如果它是您的 last/only activity不换图

当您启动一个线程时,它独立于启动它的父线程。在您的情况下,它是您的应用程序 activity。这意味着在 运行 方法完全执行之前,您的线程将一直存在。

如果退出应用程序(并因此调用activity的onStop方法),线程仍然存在,会造成内存泄漏。如果你 运行 内存不足,它最终会被系统杀死。

既然你提到你创建了一个侦听器来侦听蓝牙连接,你的线程可能在它接收到任何事件之前就死了(没有任何代码片段我不可能知道)。它也可能会崩溃,这将结束线程。

when is the worker thread killed? Is it only killed when the system actively destroys the process?

-> 工作线程在执行完 run 函数中的所有代码后就熟练了。即使你的 activity 被摧毁,它仍然 运行。

In my case, my worker thread exists as a listener for a Bluetooth connection; when received, it will fire up the desired Activity again. In this situation there is no actively running component (Activity, Service, ContentProvider or BroadcastReceiver). It seems to me that this should work, except that something is killing my worker thread.

要让它工作,在这种情况下,您需要有一个背景 service,并从您的工作线程中对您的 service 进行 soft/weak 引用或更简单,使用 EventBusService 启动任何组件:

 EventBus.getDefault().post(new BlueToothEvent()); // call in your worker thread
// do something in your service
onBlueToothEventFired(BlueToothEvent  e);