11月更文挑战|Android基础-Service简介

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

前言

ServiceAndroid设计四大组件之一,在Android开发中属于较为重要核心知识点。Service一般用于驻扎在后台执行一系列计算任务,正是因为工作在后台用户无法直接感知到它的存在。Service有两种运行模式:启动状态和绑定状态。

启动Service方式

工作状态 功能
启动状态 执行一些不在界面上显示的后台运算工作
绑定状态 和其他组件绑定并和Service交互

Service的工作状态也是相对的,两种状态可以共存,既可以和其他组件进行绑定也可以执行后台运算。

  • 通过startService启动
Intent intentService = new Intent(context,IntentService.class);
startService(intentService);
复制代码
  • 通过bindService启动
Intent intentService = new Intent(context,IntentService.class);
bindService(intentService,serviceConnection,BIND_AUTO_CREATE);
复制代码

生命周期

启动服务

  1. 第一次启动执行startService():onCreate() -> onStartCommand();
  2. 第二次Service已存在执行startService()的调用:onStartCommand();
  3. 执行stopService():onDestory()

绑定服务

  1. 执行bindService():onCreate() -> onBind();
  2. 解绑服务bindService(): onUnbind() -> onDestory()

image.png

启动过程

ServiceActivity一样都是继承ContextWrapper似乎在某些层面上看ServiceActivity有着某种相似性。一般情况下startService启动的Service是运行在App主进程中。若在AndroidManifest中对Service配置android:process属性,Service就会启动在单独进程中。

startService

Activity中调用startService方法启动Service,方法在ContextWrapper中,具体实现在ContextImpl。在ContextImpl内部执行startServiceCommon方法就会在ActivityManager.getService()获取AMS去启动Service

/// #ContextWrapper.startService
@Override
public ComponentName startService(Intent service) {
    return mBase.startService(service);
}
/// #ContextImpl.startService
@Override
public ComponentName startService(Intent service) {
       .....
    return startServiceCommon(service,false,mUser);
}
/// #ContextImpl.startServiceCommon
ComponentName cn = ActivityManager.getService().startService(mMainThread.getApplicationThread(),service,service.resolveTypeIfNeeded(getContentResolver()),requireForeground,getOpPackgetName(),getArrtibutionTag(),user.getIndetifier()));
/// #ActiveServices.startServiceLocked
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
  ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);
 ServiceRecord r = res.record;  
  ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);       
}
复制代码

可以知道启动Service其实是Context(ContextWrapper)上下文所具备的能力,在ApplicationActivityService中都是可以调用的,最终都是会走到ContextImpl.startService

  1. ContextImpl.StartService
  2. ContextImpl.startServiceCommon
  3. ActivityManager.getService().startService()
  4. ActivityManagerService.startService()
  5. ActiveServices.startServiceLocked()
  6. ActiveServices.startServiceInnerLocked()
  7. ActiveServices.bringUpServiceLocked()
  8. ActiveServices.realStartServiceLocked()

(1、2)在当前Context下向SystemServer发起启动Service请求

(3、4、5、6)在SystemServer进程中处理请求

(7)处理Service启动核心逻辑

(8)AMS和ActivityThread IPC交互过程,创建Service实例并启动。

扫描二维码关注公众号,回复: 13276709 查看本文章

猜你喜欢

转载自juejin.im/post/7032606590771396616
今日推荐