AndroidService是啥?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AndroidService是啥?相关的知识,希望对你有一定的参考价值。
Service,看名字就知道跟正常理解的“服务”差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,但是他不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startService() 和 Context.bindService()。两种启动Service的方式有所不同。这里要说明一下的是如果你在Service的onCreate或者onStart做一些很耗时间的事情,最好在Service里启动一个线程来完成,因为Service是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情。
什么时候需要Service呢?比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。 参考技术A Service就是一个应用程序组件,用来执行一些长时间的操作,然而不与用户交互或者为其他应用程序提供一些功能。每一个Service类都必须定义在androidManifest.xml中,以<service>tag开头。
Android Service 流程分析
- 《Android Service基础》
- 《Android Service回调和配置》
- 《Android Service aidl使用及进阶》
- 《Android Service更多知识》
- 《Android 中的 IntentService 类详解》
- 《Android Service aidl分析》
- 《Android Service 流程分析》
在前面已经对Service基本使用及aidl使用及源码进行的分析。在这篇文章中,我们来看一下Android Service的启动流程和绑定流程,以便于更好的理解Android Service的机制。
启动Service过程
Android Service启动时序图
上图就是Android Service启动时序图,对照图查看代码。
我们在 Activity 中调用 startService()
方法时,直接调用了 调用 ContextWrapper
的 startService()
@Override
public ComponentName startService(Intent service)
return mBase.startService(service);
mBase 就是 ContextImpl
,进入 ContextImpl
中查看
@Override
public ComponentName startService(Intent service)
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user)
try
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
// ActivityManager.getService() 就是获取到的 ActivityManagerService 对象
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
// ... 省略 对 cn 进行校验
return cn;
catch (RemoteException e)
throw e.rethrowFromSystemServer();
ActivityManager
中获取 ActivityManagerService
代码如下:
public static IActivityManager getService()
return IActivityManagerSingleton.get();
// 通过 Singleton 创建IActivityManager.aidl接口对象,实现类为 `ActivityManagerService`
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>()
@Override
protected IActivityManager create()
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 由一下代码可知,IActivityManager 是aidl,也就说明Service的启动过程是一个IPC的过程
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
;
进入 ActivityManagerService
中查看 startService()
方法
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException
enforceNotIsolatedCaller("startService");
// ... 省略 Refuse possible leaked file descriptors 对service文件描述和调用包进行判断
synchronized(this)
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try
// 调用 ActiveServices 的 startServiceLocked() 方法
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
finally
Binder.restoreCallingIdentity(origId);
return res;
mServices 是 ActiveServices
类,该类是 AMS(ActivityManagerService
) 的辅助类,是对 Service
进行管理的工具类,包含Service的启动、绑定、解绑、销毁等过程。查看 ActiveServices
的 startServiceLocked()
方法,一下是ActiveServices
中的方法调用过程:
// ActiveServices#startServiceLocked()
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException
// 调用 startServiceLocked()
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, userId, false);
// ActiveServices#startServiceLocked()
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
final int userId, boolean allowBackgroundActivityStarts)
throws TransactionTooLargeException
// ... 省略
ServiceLookupResult res =
retrieveServiceLocked(service, null, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
// 取出 ServiceRecord 对象,后面启动过程中都是使用的它
ServiceRecord r = res.record;
// ... 省略 判断和处理前台服务
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true; // 启动服务标识置为 true
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid));
// 调用 startServiceInnerLocked() 方法
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
// ActiveServices#startServiceInnerLocked()
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException
// ... 省略
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
// ... 省略
return r.name;
// ActiveServices#bringUpServiceLocked()
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException
// 已经启动,重复启动时,直接发送参数调动 onStartCommand() 方法
if (r.app != null && r.app.thread != null)
sendServiceArgsLocked(r, execInFg, false);
return null;
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
ProcessRecord app;
if (!isolated)
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
if (app != null && app.thread != null)
try
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
// 调用 realStartServiceLocked() 方法
realStartServiceLocked(r, app, execInFg);
return null;
catch (TransactionTooLargeException e)
throw e;
catch (RemoteException e)
Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
else
// ... 省略
// ... 省略
return null;
// ActiveServices#realStartServiceLocked()
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException
boolean created = false;
try
// 调用 ActivityThread 的 scheduleCreateService() 方法
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
r.postNotification();
created = true;
catch (DeadObjectException e)
throw e;
finally
// ... 省略
// ... 省略
// 如果是启动,并且需要调用 onStartCommand() 方法,给 pendingStarts 集合增加数据,
// 因为 onStartCommand() 方法是否会调动是根据 pendingStarts 集合是否有数据来决定是否调用的。
// 在后面说参数调用的时候就会知道,如果仅仅是绑定服务,就不会添加,这也就是为什么我们绑定服务时不会回调 onStartCommand() 方法的原因
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0)
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null, 0));
// 调用方法,处理参数,从而调用 onStartCommand() 方法
sendServiceArgsLocked(r, execInFg, true);
从这里开始分为两步,先通过 ActivityThread
中的方法来启动 Service
,然后在通过 ActiveServices
自身的 sendServiceArgsLocked()
方法来处理参数(Intent数据),调用生命周期的 onStartCommand()
方法。注意注释部分,说明了我们仅仅是绑定服务时为什么不会回调 onStartCommand()
方法的原因,后面说绑定Service不会在重复了。
启动过程(attach() 和 onCreate() 方法回调过程)
先看 ActivityThread
中的方法
// ActivityThread#scheduleCreateService()
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState)
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
// 给 Handler 类 H 发送 CREATE_SERVICE
// H 是 ActivityThread 的内部类,继承 Handler
sendMessage(H.CREATE_SERVICE, s);
Handler 类 H handleMessage()
方法针对 what 为 CREATE_SERVICE
的处理,调用 handleCreateService()
方法
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
调用 handleCreateService()
方法,内部通过类加载器创建Service东西,然后调用Service的 attach()
和 onCreate()
方法
// ActivityThread#handleCreateService()
private void handleCreateService(CreateServiceData data)
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try
// 使用类加载器通过反射的形势创建Service对象
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
catch (Exception e)
try
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
// Serivce 的 attach() 回调,并建立 Service 和 ContextImpl 之间的联系
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
service.onCreate(); // Serivce 的 onCreate() 回调
// 将Service保存到集合中 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
mServices.put(data.token, service);
catch (Exception e)
通过类加载器创建Service的过程如下:
通过类 LoadedApk#getAppFactory()
方法可以知道获取到的是 AppComponentFactory
对象,
public AppComponentFactory getAppFactory()
return mAppComponentFactory;
// 给 mAppComponentFactory 赋值
private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl)
if (appInfo.appComponentFactory != null && cl != null)
try
return (AppComponentFactory) cl.loadClass(appInfo.appComponentFactory).newInstance();
catch (InstantiationException | IllegalAccessException | ClassNotFoundException e)
Slog.e(TAG, "Unable to instantiate appComponentFactory", e);
return AppComponentFactory.DEFAULT;
然后调用 AppComponentFactory#instantiateService()
方法,创建Service类,方法实现如下:
public @NonNull Service instantiateService(@NonNull ClassLoader cl,
@NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException
// 通过反射创建Service
return (Service) cl.loadClass(className).newInstance();
上面说了,分为两步。先是启动 Service
;然后在处理参数。通过以上步骤,我们知道 Service
已经启动了,它的 attach()
和 onCreate()
都已经调用了,下面我们来看看它的生命周期方法
onStartCommand()
在什么时候调用,在上面已经说过是通过 ActiveServices
自身的 sendServiceArgsLocked()
方法来处理的
参数处理(onStartCommand() 方法回调过程)
// ActiveServices#sendServiceArgsLocked() 方法
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException
final int N = r.pendingStarts.size();
// 集合中没有数据,直接返回。
// 如果仅仅是绑定服务,大小为0,这也就是为什么我们绑定服务时不会回调 onStartCommand() 方法的原因
// 上面 ActiveServices#realStartServiceLocked() 注释
if (N == 0)
return;
ArrayList<ServiceStartArgs> args = new ArrayList<>();
// ... 省略 r.pendingStarts 参数处理部分
ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
slice.setInlineCountLimit(4);
Exception caughtException = null;
try
// 调用 ActivityThread 的 scheduleServiceArgs() 方法
r.app.thread.scheduleServiceArgs(r, slice);
catch (TransactionTooLargeException e)
上面当 r.pendingStarts.size()
为0时,不会继续执行,也就是当仅仅是绑定Service时,不会执行后面的步骤了。接着看 ActivityThread
中的 scheduleServiceArgs()
方法
// ActivityThread#scheduleServiceArgs()
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args)
List<ServiceStartArgs> list = args.getList();
for (int i = 0; i < list.size(); i++)
ServiceStartArgs ssa = list.get(i);
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = ssa.taskRemoved;
s.startId = ssa.startId;
s.flags = ssa.flags;
s.args = ssa.args;
// 给 Handler 类 H 发送 SERVICE_ARGS
sendMessage(H.SERVICE_ARGS, s);
Handler 类 H handleMessage()
方法针对 what 为 SERVICE_ARGS
的处理,调用 handleServiceArgs()
方法
case SERVICE_ARGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
调用 handleServiceArgs()
方法,在方法内部调用 Serivce 的 onStartCommand()
回调
// ActivityThread#handleServiceArgs()
private void handleServiceArgs(ServiceArgsData data)
Service s = mServices.get(data.token);
if (s != null)
try
if (data.args != null)
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
int res;
if (!data.taskRemoved)
// Serivce 的 onStartCommand() 回调
res = s.onStartCommand(data.args, data.flags, data.startId);
else
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
QueuedWork.waitToFinish();
try
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
catch (RemoteException e)
throw e.rethrowFromSystemServer();
catch (Exception e)
以上就是Android中的Service启动流程,就是通过AMS(ActivityManagerService
)借助 ActiveServices
来完成,由AMS的定义ActivityManagerService extends IActivityManager.Stub
可知这也是一个IPC过程,最后则都是通过 ActivityThread
来内部类H来处理(H是主线程的Handler),主线程的Loop由 ActivityThread 的 main()
方法开启
// ActivityThread#main()
public static void main(String[] args)
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null)
sMainThreadHandler = thread.getHandler();
Looper.loop();
绑定Service过程
Android Service绑定时序图
上图就是Android Service启动时序图,绑定Service我们也需要启动Service,也就是需要调用Service 的 attach()
和 onCreate()
方法,由图可知,在调用这两个方法的过程中,ActiveServices
和 ActivityThread
中间的过程是一样的。
我们具体的来看一下
我们在 Activity 中调用 bindService()
方法时,直接调用了 调用 ContextWrapper
的 bindService()
,接着调用 ContextImpl
的 bindService()
,查看 ContextImpl
中的代码
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags)
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, getUser());
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user)
IServiceConnection sd;
// mPackageInfo 为 LoadedApk
if (mPackageInfo != null)
if (executor != null)
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
else
// handler不为null,将 ServiceConnection 封装成 IServiceConnection
// IServiceConnection 就是 LoadedApk.ServiceDispatcher.InnerConnection 类
// 将 conn 保持到InnerConnection中,handler 为主线程Handler,也就是 ActivityThread的内部类 H 对象
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
else
throw new RuntimeException("Not supported in system context");
validateServiceIntent(service);
try
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
flags |= BIND_WAIVE_PRIORITY;
service.prepareToLeaveProcess(this);
// 调用 AMS 的 bindIsolatedService() 方法
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
if (res < 0)
throw new SecurityException(
"Not allowed to bind to service " + service);
return res != 0;
catch (RemoteException e)
throw e.rethrowFromSystemServer();
**注意:**在这里需要注意以上注释的地方,因为绑定Service最终客户端要回调 ServiceConnection
对象的 onServiceConnected()
方法,mPackageInfo.getServiceDispatcher()
就是将我们调用 bindService()
方法传递的 ServiceConnection
对象 封装成 IServiceConnection
(实现为 LoadedApk#ServiceDispatcher#InnerConnection 类,定义为 InnerConnection extends IServiceConnection.Stub
)这是一个aidl接口,这是因为Service启动和绑定时跨进程的,普通的 ServiceConnection
是不能款进程传输的,所以需要进行封装与转换成aidl类型。
先看绑定Service的启动过程
调用 AMS 的 bindIsolatedService() 方法
// ActivityManagerService#bindIsolatedService()
public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException
synchronized(this)
// 调用 ActiveServices 的 bindServiceLocked() 方法
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
由AMS调用 ActiveServices
中的 bindServiceLocked()
方法
// ActiveServices#bindServiceLocked()
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, final int userId)
throws TransactionTooLargeException
// ... 省略
// 绑定服务时,调用 ServiceRecord 的 retrieveAppBindingLocked() 方法,
// 在该方法中给 ServiceRecord的bindings 添加绑定记录
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage);
IBinder binder = connection.asBinder();
// 保存到 ServiceRecord 的 connections 集合中
s.addConnection(binder, c);
b.connections.add(c);
// ... 省略
if ((flags&Context.BIND_AUTO_CREATE) != 0)
s.lastActivity = SystemClock.uptimeMillis();
// 调用 bringUpServiceLocked() 方法,后面的启动过程和启动Service一样
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null)
return 0;
// ... 省略
return 1;
注意,上面注释部分,绑定服务时,我们将连接对象保存到了 ServiceRecord 中。
绑定服务到这里,后面调用 attach() 和 onCreate() 方法就和启动服务时一样的了,在 bringUpServiceLocked()
中 调用
realStartServiceLocked()
方法,接着继续往下调用。
和启动Service不一样的是,在 realStartServiceLocked()
方法中会调用 requestServiceBindingsLocked()
方法,处理绑定服务的过程
绑定过程(onBind() 或者 onRebind() 方法回调过程)
ActiveServices
中的requestServiceBindingsLocked()
方法
// ActiveServices#requestServiceBindingsLocked()
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException
// 根据 ServiceRecord的bindings 是否有数据调用 requestServiceBindingLocked() 方法,在上一步给它添加了数据
for (int i=r.bindings.size()-1; i>=0; i--)
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false))
break;
根据是否有连接对象判断是否需要调用 ActiveServices
中的requestServiceBindingLocked()
方法,绑定Service在 ActiveServices
中的 bindServiceLocked()
方法中添加了,所以集合肯定不会为空
// ActiveServices#requestServiceBindingLocked()
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException
if ((!i.requested || rebind) && i.apps.size() > 0)
try
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
// 调用 ActivityThread 的 scheduleBindService() 方法
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.getReportedProcState());
if (!rebind)
i.requested = true;
i.hasBound = true;
i.doRebind = false;
catch (TransactionTooLargeException e)
return false;
return true;
继续进入 ActivityThread
中调用 scheduleBindService()
方法
// ActivityThread#scheduleBindService
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState)
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind;
// 给 Handler 类 H 发送 BIND_SERVICE
sendMessage(H.BIND_SERVICE, s);
Handler 类 H handleMessage()
方法针对 what 为 BIND_SERVICE
的处理,调用 handleBindService()
方法
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
ActivityThread
中调用 handleBindService()
方法
// ActivityThread#handleBindService
private void handleBindService(BindServiceData data)
Service s = mServices.get(data.token);
if (s != null)
try
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try
if (!data.rebind)
// 调用 Service 的 onBind() 方法
IBinder binder = s.onBind(data.intent);
// 这里调用 ActivityManagerService 的 publishService() 方法,
ActivityManager.getService().publishService(
data.token, data.intent, binder);
else
// 如果是重新绑定,就调用 Service 的 onRebind() 方法
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
catch (RemoteException ex)
throw ex.rethrowFromSystemServer();
catch (Exception e)
if (!mInstrumentation.onException(s, e))
throw new RuntimeException(
"Unable to bind to service " + s
+ " with " + data.intent + ": " + e.toString(), e);
在上面的方法中我们已经看到了 Service 的 onBind()
或者 onRebind()
方法已经被调用了,那么对于Service类来说已经执行完成了。但是我们绑定Service,客户端需要拿到IBinder对象,这个对象是在 ServiceConnection
对象的回调 onServiceConnected()
方法取到的,所以我们继续看看这个过程是怎样的。
调用 ServiceConnection
对象的回调 onServiceConnected()
方法过程
// 这里调用 ActivityManagerService 的 publishService() 方法,
ActivityManager.getService().publishService(data.token, data.intent, binder);
查看以上这句代码,调用 ActivityManagerService
的 publishService()
方法
// ActivityManagerService#publishService()
public void publishService(IBinder token, Intent intent, IBinder service)
synchronized(this)
if (!(token instanceof ServiceRecord))
throw new IllegalArgumentException("Invalid service token");
// 调用 ActiveServices 的 publishServiceLocked() 方法
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
然后调用 ActiveServices
的 publishServiceLocked()
方法
// ActiveServices#publishServiceLocked()
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service)
// 从 ServiceRecord 的 connections 集合中取出数据
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--)
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
for (int i=0; i<clist.size(); i++)
ConnectionRecord c = clist.get(i);
try
// c.conn 为 IServiceConnection 对象
// 实际就是 LoadedApk.ServiceDispatcher.InnerConnection 类
c.conn.connected(r.name, service, false);
catch (Exception e)
这个地方我们先从 ServiceRecord 取出数据,取出来的数据就是包含了客户端 ServiceConnection
对象的aidl接口对象 IServiceConnection
(实现类为 LoadedApk#ServiceDispatcher#InnerConnection),所以调用的就是 LoadedApk#ServiceDispatcher#InnerConnection 的 connected()
方法
// LoadedApk 内部类 InnerConnection 的 connected() 方法,也就是上面的 c.conn.connected() 方法
private static class InnerConnection extends IServiceConnection.Stub
@UnsupportedAppUsage
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd)
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null)
// 调用 LoadedApk.ServiceDispatcher 的 connected() 方法
sd.connected(name, service, dead);
调用 LoadedApk#ServiceDispatcher 的 connected()
方法
// LoadedApk.ServiceDispatcher#connected()
public void connected(ComponentName name, IBinder service, boolean dead)
if (mActivityExecutor != null)
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
else if (mActivityThread != null)
// 由 ContextImpl#bindServiceCommon() 方法中可知,mActivityThread 就是 ActivityThread 的 H对象(主线程的Handler),不为null
// RunConnection 的 run方法中调用 doConnected() 方法
// 因为是通过主线程的Handler调用的方法,所以客户端的ServiceConnection#onServiceConnected()运行在主线程
mActivityThread.post(new RunConnection(name, service, 0, dead));
else
doConnected(name, service, dead);
由前面的代码可知,这里的 mActivityThread 不会为 null ,而且就是就是 ActivityThread 的 H对象(主线程的Handler),会调用mActivityThread.post
运行任务。RunConnection 代码如下:
// RunConnection 类代码
private final class RunConnection implements Runnable
public void run()
if (mCommand == 0)
// 调用 doConnected() 方法
doConnected(mName, mService, mDead);
else if (mCommand == 1)
doDeath(mName, mService);
在 RunConnection 中调用 LoadedApk 类的 doConnected()
方法
// LoadedApk#doConnected()
public void doConnected(ComponentName name, IBinder service, boolean dead)
// ... 省略
// 由 ContextImpl#bindServiceCommon() 方法中可知,mConnection 就是客户端的 ServiceConnection 对象,回调它的 onServiceConnected() 方法,完成绑定过程
if (service != null)
mConnection.onServiceConnected(name, service);
else
// The binding machinery worked, but the remote returned null from onBind().
mConnection.onNullBinding(name);
service不为null时,调用 mconnection 的 onServiceConnected()
方法,mconnection 就是客户端的 ServiceConnection
对象,在前面 ContextImpl
的 bindServiceCommon()
方法说明时有注释进行说明了。
以上就是绑定Service以及回调给客户端IBinder东西的完整过程,也就是我们在使用绑定Service时系统的调用过程。对于解绑和停止Service相关类也就是这些,这里就一一贴出代码了,一下提供解绑Service和停止Service的时序图。
解绑Service过程
停止Service过程
以上是关于AndroidService是啥?的主要内容,如果未能解决你的问题,请参考以下文章