继续研究Android的官方文档又有新的发现,现记录如下:
在默认的情况下,Android Service提供了一个可以在后台运行服务,那么这个在后台运行的Service其实是运行在主线程(UI 线程)里的。
google官网对Service的解释如下:
Thus a Service itself is actually very simple, providing two main features:
- A facility for the application to tell the system about something it wants to be doing in the background (even when the user is not directly interacting with the application). This corresponds to calls to
Context.startService()
, which ask the system to schedule work for the service, to be run until the service or someone else explicitly stop it. - A facility for an application to expose some of its functionality to other applications. This corresponds to calls to
Context.bindService()
, which allows a long-standing connection to be made to the service in order to interact with it.
----------------------------------------------------------------------------------------------------------------------------------------------------------
这里我要反省自己之前犯的一个错误,希望大家不要犯同样的错误:
之前在CMMB的维护工作中,发现CMMB在启动/退出的时候会开启/停掉自己的相关服务MBBMSService,但是服务的退出比较耗时,会有一定的概率产生ANR。
当时我是这样处理这个问题的,CMMB 应用要停服务的时候会调用stopService,当时我把stopService的调用放到了一个单独线程中去做。我本来以为这样停止MBBMSService的操作会在一个单独的线程中做。结果仍然有ANR,原来我这么做并不能保证MBBMSService退出操作在一个独立线程做。因为调用stopService停止相应服务的时候,会回调MBBMSService中的onDestroy。在这个onDestroy在做具体的服务注销操作(耗时),但是这个onDestroy回调仍然在主线程中做,所以无法避免anr。对于这样的问题,应该在MBBMSService中将具体的耗时操作提出来,放到线程中做。但是这样可能会带来一些同步的问题,所以大家要慢慢Debug咯。
OK言归正传,如何让service运行在一个新的process中呢?原来我们在AndroidManifest.xml文件中:
-
<service android:enabled=["true" | "false"] android:exported=["true" | "false"] android:icon="drawable resource" android:label="string resource" android:name="string" android:permission="string" android:process="string" > . . . </service>
-
The name of the process where the service is to run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The
<application>
element'sprocess
attribute can set a different default for all components. But component can override the defaultwith its ownprocess
attribute, allowing you to spread your application across multiple processes.If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process.If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so.This allows components in different applications to share a process, reducing resource usage.
android:process
关于IPC在应用层的实现方式,我还要继续学习下.......