5.1.2 组件的应用进程配置
在默认配置下,同一应用中的所有组件,都构造并运行在该应用的进程中。这样的模式符合大部分应用的需求。但在有些场景下,将同一应用中的不同组件拆分到多个应用进程中独立运行,是非常必要的。
比如,在应用中,某个服务组件的服务对象不是本应用中的其他组件,而是供第三方应用组件进行绑定和调用的。如果将该服务组件与应用中的其他组件放在同一进程中,那么它的运行会增加该应用进程的空间和时间开销,从而影响本应用中其他的组件与用户的正常交互。因此,需要将该服务组件隔离到独立的应用进程中,以保证整个应用能够更顺畅地运行。
在Android中,每个组件都可以通过配置文件中组件配置项的android:process属性,将该组件部署到其他应用进程中运行。比如,如果将一个服务组件放入新的应用进程,可进行如下配置:
<service android:process=":another"…/>
例中,如果android:process的值以冒号开头,说明这是一个私有进程,仅能放置本应用的组件,其他应用无法共享该进程空间;如果该值以一个小写字母开头,说明这是一个共享进程,可以承载来自不同应用的组件。共享进程的使用需要额外的权限,大部分的非原生应用开发使用的都是私有进程。
配置了android:process信息的组件运行模型如图5-2所示。可以看到,应用com.duguhome.sample中的组件,被分离到两个应用进程中运行,每个应用进程都有独立的应用环境对象,彼此之间不能互联互通。因此,在这种情况下,应用环境对象并不能承载整个应用的全局信息。
在实际开发中,通常会将逻辑上在一起运行的组件配置到同一进程中。比如,如果通过设置android:process将一个服务组件放到了一个私有的进程中,那么就需要将调用该服务组件的触发器组件也放入该进程中。否则,当该触发器组件监听到相关事件时,系统会先为它构建一个应用进程,紧接着,再为它调用的服务组件启动另一应用进程(可能还会立刻销毁第一个应用进程),从而增加了系统开销,降低了运行效率。
图 5-2 应用进程的配置
除了android:process属性,组件配置项的android:mutiprocess属性也是控制组件进程模型的重要手段。在四大组件中,数据源组件和界面组件都可以通过android:mutiprocess属性进行配置。android:mutiprocess的默认值为false,表示该组件的对象构造和运行在与该应用相关联的应用进程中(可以是默认进程,也可以是通过android:process指定的进程)。
在这种配置下,如果组件被第三方应用调用,就会同时启用两个进程:第三方应用所在的应用进程和该组件所在的应用进程。为了节省进程开销,开发者可以通过配置文件将android:mutiprocess设置为true:
<provider android:mutiprocess="true"…/>
此时,应用就会将该组件“嫁”出去,当任何一个第三方应用调用该组件时,都会在这个第三方应用进程中构造一个组件对象,而不再是运行于该组件所在的应用进程中。
在这样的模式下,该组件在系统中的对象数量将会有所增加,但可以使调用组件与该组件的关联更为紧密。以数据源组件为例,在调用应用进程中构造数据源组件对象,可以使调用组件与数据源组件的数据交互成为进程内通信,从而降低了数据在进程间传输的开销[1]。
在实际开发中,使用android:mutiprocess属性会为组件开发带来很多的并发复杂性,因此并不常使用该属性。
[1]关于数据源组件的不同使用方式的利弊,可以参见第3章的相关介绍。