如何在Android中启动服务

  介绍

如何在Android中启动服务?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

<强> Android服务的启动过程分析

启动一个服务只需调用上下文的startService方法,传进一个意图即可。看起来好像很简单的说,那是因为Android为了方便开发者,做了很大程度的封装。那么你真的有去学习过服务是怎么启动的吗?服务的onCreate方法回调前都做了哪些准备工作?

先上一张图大致了解下,灰色背景框起来的是同一个类中的方法,如下图:

<强>服务启动过程

如何在Android中启动服务”> </p> <p>那接下来就从源码的角度来分析服务的启动过程。</p> <p>当然是从上下文的startService方法开始,上下文的实现类是ContextImpl,那么我们就看到ContextImpl的startService方法即可,如下:</p> <pre类= @Override   公共ComponentName startService(意图服务){   warnIfCallingFromSystemProcess ();   返回startServiceCommon(服务,沉思者);   }

会转到startServiceCommon方法,那跟进startServiceCommon方法方法瞧瞧。

 @Override
  公共ComponentName startService (IApplicationThread调用者,意图服务,
  字符串resolvedType、字符串callingPackage int userId)
  抛出TransactionTooLargeException {//代码省略
  
  同步(){
  最后一个int callingPid=Binder.getCallingPid ();
  最后一个int callingUid=Binder.getCallingUid ();
  最后长origId=Binder.clearCallingIdentity ();
  ComponentName res=mServices。startServiceLocked(调用者、服务
  resolvedType、callingPid callingUid、callingPackage userId);
  Binder.restoreCallingIdentity (origId);
  返回res;
  }
  }

在上述的代码中,调用了ActiveServices的startServiceLocked方法,那么现在服务的启动过程从AMS转移到了ActiveServices了。

继续跟进ActiveServices的startServiceLocked方法,如下:

 ComponentName startServiceLocked (resolvedType IApplicationThread调用者,意图服务,字符串,
  int callingPid, int callingUid字符串callingPackage, int userId)
  抛出TransactionTooLargeException {//代码省略
  
  ServiceLookupResult res=retrieveServiceLocked(服务、resolvedType callingPackage
  callingPid、callingUid userId,真的,callerFg);//代码省略
  
  
  ServiceRecord r=res.record;//代码省略
  
  返回startServiceInnerLocked (smap、服务r, callerFg addToStarting);
  }

在startServiceLocked方法中又会调用startServiceInnerLocked方法,

我们瞧瞧startServiceInnerLocked方法,

 ComponentName startServiceInnerLocked (ServiceMap smap,意图服务,ServiceRecord r,
  布尔callerFg,布尔addToStarting)抛出TransactionTooLargeException {
  ProcessStats。ServiceState斯特拉克=r.getTracker ();
  如果(斯特拉克!=null) {
  斯特拉克。r.lastActivity setStarted(真的,mAm.mProcessStats.getMemFactorLocked ());
  }
  r。callStart=false;
  同步(r.stats.getBatteryStats ()) {
  r.stats.startRunningLocked ();
  }
  字符串错误=bringUpServiceLocked (r, service.getFlags (), callerFg,假);//代码省略
  
  返回r.name;
  }

startServiceInnerLocked方法内部调用了bringUpServiceLocked方法,此时启动过程已经快要离开ActiveServices了。继续看到bringUpServiceLocked方法。如下:

如何在Android中启动服务