【磨叽教程】Android进阶教程之在Android系统下各进程之间的优先级关系

首先应用进程的生命周期并不由应用本身直接控制,而是由系统综合多种因素来确定的。**Android系统有自己的一套标准,它可以根据这套标准区分当前运行的所有进程的重要性。**这是 Android 非常独特的一个基本功能。(关注公众号“计算机自学平台“获取更多信息)
在大多数情况下,**每个 Android 应用都在各自的 Linux 进程中运行。**当需要运行应用的一些代码时,系统会为应用创建此进程,并使其保持运行,直到不再需要它或者系统内存不足需要回收以供其他应用使用才会终止它。
我们作为应用开发者必须了解不同的应用组件(特别是 Activity、Service 和 BroadcastReceiver)对应用进程的生命周期影响。这些组件使用不当会导致你的应用进程直接被终止,比如系统需要执行重要任务时。
举个我们常见的例子:
在我们使用 BroadcastReceiver 的 BroadcastReceiver.onReceive() 方法中接收到一个 Intent 时,它会启动一个线程,并从该函数返回。可是一旦返回,系统会认为 BroadcastReceiver 不再处于活动状态,然后就不再托管进程(除非其中有其他应用组件处于活动状态)。因此,系统可能会随时终止进程以回收内存,这样会导致在进程中运行的衍生线程直接终止而给我们的应用带来重大影响。
解决办法:
要解决这个问题,通常可以从 BroadcastReceiver 调度 JobService,这样系统就知道进程中还有处于活动状态的任务正在进行中,从而不会去主动终止它。
但是,在系统内存不足的时候,系统还是会去终止一些应用的进程来释放足够的内存来保证系统的稳定性。要想了解系统是怎么选择被终止进程的,那就需要我们足够的了解系统“重要性优先级”:

前台进程是用户目前执行操作所需的进程。在不同的情况下,进程可能会因为其所包含的各种应用组件而被视为前台进程。如果以下任一条件成立,则进程会被认为位于前台:

条件一:它正在用户的互动屏幕上运行一个 Activit(其 onResume() 方法已被调用)。
条件二:它有一个 BroadcastReceiver 目前正在运行(其 BroadcastReceiver.onReceive() 方法正在执行)。

条件三:它有一个 Service 目前正在执行其某个回调(Service.onCreate()、Service.onStart() 或 Service.onDestroy())中的代码。
系统中只有少数此类进程,而且除非内存过低,导致连这些进程都无法继续运行,才会在最后一步终止这些进程。

可见进程正在进行用户当前知晓的任务,因此终止该进程会对用户体验造成明显的负面影响。在以下条件下,进程将被视为可见:

条件一:它正在运行的 Activity 在屏幕上对用户可见,但不在前台(其 onPause() 方法已被调用)。举例来说,如果前台 Activity 显示为一个对话框,而这个对话框允许在其后面看到上一个 Activity,则可能会出现这种情况。
条件二:它有一个 Service 正在通过 Service.startForeground()(要求系统将该服务视为用户知晓或基本上对用户可见的服务)作为前台服务运行。
条件三:系统正在使用其托管的服务实现用户知晓的特定功能,例如动态壁纸、输入法服务等

相比前台进程,系统中运行的这些进程数量较不受限制,但仍相对受控。这些进程被认为非常重要,除非系统为了使所有前台进程保持运行而需要终止它们,否则不会这么做。

服务进程包含一个已使用 startService() 方法启动的 Service。虽然用户无法直接看到这些进程,但它们通常正在执行用户关心的任务(例如后台网络数据上传或下载),因此系统会始终使此类进程保持运行,除非没有足够的内存来保留所有前台和可见进程。

已经运行了很长时间(例如 30 分钟或更长时间)的服务的重要性可能会降位,以使其进程降至下文所述的缓存 LRU
列表。这有助于避免超长时间运行的服务因内存泄露或其他问题占用大量内存,进而妨碍系统有效利用缓存进程。

缓存进程是目前不需要的进程,因此,如果其他地方需要内存,系统可以根据需要自由地终止该进程。在正常运行的系统中,这些是内存管理中涉及的唯一进程:运行良好的系统将始终有多个缓存进程可用(为了更高效地切换应用),并根据需要定期终止最早的进程。只有在非常危急(且具有不良影响)的情况下,系统中的所有缓存进程才会被终止,此时系统必须开始终止服务进程。
这些进程通常包含用户当前不可见的一个或多个 Activity 实例(onStop() 方法已被调用并返回)。只要它们正确实现其 Activity 生命周期(详情请见 Activity),那么当系统终止此类流程时,就不会影响用户返回该应用时的体验,因为当关联的 Activity 在新的进程中重新创建时,它可以恢复之前保存的状态。
这些进程保存在伪 LRU 列表中,列表中的最后一个进程是为了回收内存而终止的第一个进程。此列表的确切排序政策是平台的实现细节,但它通常会先尝试保留更多有用的进程(比如托管用户的主屏幕应用、用户最后看到的 Activity 的进程等),再保留其他类型的进程。还可以针对终止进程应用其他政策:比如对允许的进程数量的硬限制,对进程可持续保持缓存状态的时间长短的限制等。

在决定如何对进程进行分类时,系统会参考进程中当前活动的所有组件中最重要的级别。

进程的优先级也可能因从属于进程的其他依赖项而提升例如,如果进程 A 已通过 Context.BIND_AUTO_CREATE 标记绑定到 Service,或在使用进程 B 中的 ContentProvider,则进程 B 的分类始终至少和进程 A 一样重要。

猜你喜欢

转载自blog.csdn.net/farley119/article/details/107996676