从源码出发深入理解 Android Service

来源:互联网 发布:消费者数据库 编辑:程序博客网 时间:2024/05/16 14:09

0X00 Service 基础知识

Service 作为 Android 提供的四大组件之一,主要负责一些没有前台显示的后台任务。即使应用本身不再可见,Service 的属性也能使得其在后台运行。除此之外,Service 也可以通过 Binder 机制,与界面甚至其他应用进行进程间通信,以实现相应的交互。这里需要简单说明的是,既然是后台任务,为什么不选用 Thread 了?选用 Service 和 Thread 的主要区别在于需不需要在应用不可见的时候依然保留。举例来说,新闻详情页面的数据请求,只用在当前页面生效,而音乐播放这些后台任务就可以通过 Service 的方式来实现。

关于如何使用 Service,官方教程已经说明得足够详细了,如果对这些用法,还有不清晰的地方,请戳这里进行查看,-> 官方教程。官方教程里面包括,startService 和 bindService 的区别,在不同场景下应该选用哪种 Service 实现方式。

Service 生命周期


0X01 startService 调用流程

从前面的教程里面,可以知道 Service 的启动一般有两种方式,分别是 bindService 和 startService。这里主要说明 startService, 具体的实现逻辑在 ContextImpl 中,我们看看源码是怎么实现的。

@Overridepublic ComponentName startService(Intent service) {    warnIfCallingFromSystemProcess();    return startServiceCommon(service, mUser);}

接下来,看看方法内部具体是怎么实现的。

private ComponentName startServiceCommon(Intent service, UserHandle user) {    try {        validateServiceIntent(service);        service.prepareToLeaveProcess();        ComponentName cn = ActivityManagerNative.getDefault().startService(            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(                        getContentResolver()), getOpPackageName(), user.getIdentifier());        // ignore some codes...        return cn;    } catch (RemoteException e) {        throw new RuntimeException("Failure from system", e);    }}

从上面的代码可以看到,这里是通过 ActivityManagerNative 来执行的。如果看过我的另一篇文章,Android Activity 生命周期是如何实现的, 可能会觉得很熟悉。事实上这里采用的机制就是同样的。

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {    protected IActivityManager create() {        IBinder b = ServiceManager.getService("activity");        if (false) {            Log.v("ActivityManager", "default service binder = " + b);        }        IActivityManager am = asInterface(b);        if (false) {            Log.v("ActivityManager", "default service = " + am);        }        return am;    }};

ActivityManagerNative 的 getDefault 方法是这么实现的。可以看到,gDefault 是类型为 IActivityManager 的 Binder 对象。而这个 Binder 对象可以看做是在 System Server 中的 ActivityManagerService 的句柄,通过这个 Binder 对象,可以跨进程调用 ActivityManagerService。

如果上述内容不容易理解的话,我们可以类比地来看这个问题。我们遥控电视的时候,例如进行增加音量的操作,这个操作实际不是由遥控器完成的,而是电视中的电子元件完成的。遥控器会和电视进行协商,先声明有哪些操作可以执行,然后将这些协商后的操作在遥控器端和电视端

0 0
原创粉丝点击