Service进阶篇(startService)
来源:互联网 发布:鸿星网络 编辑:程序博客网 时间:2024/05/16 09:11
先附上一张startService工作的流程图
1.从从Service 的启动过程ContextWrapper 的startService开始:
Context mBase; @Override public ComponentName startService(Intent service) { return mBase.startService(service); }
class ContextImpl extends Context
我的另一边文章:Activity源码分析中 已知Actiivty在创建时会把一个ContextImpl对象关联起来,这个ContextImpl就是mBase。查看ContextImpl的startService方法。
@Override public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, mUser); }private ComponentName startServiceCommon(Intent service, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(this); ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( getContentResolver()), getOpPackageName(), user.getIdentifier()); if (cn != null) { if (cn.getPackageName().equals("!")) { throw new SecurityException( "Not allowed to start service " + service + " without permission " + cn.getClassName()); } else if (cn.getPackageName().equals("!!")) { throw new SecurityException( "Unable to start service " + service + ": " + cn.getClassName()); } } return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
startService方法调用了startServiceCommon方法,而startServiceCommon又通过ActivityManagerNative.getDefault().startService方法来开启一个服务。ActivityManagerNative.getDefault()返回的是ActivityManagerService(AMS),这点已在:Activity源码分析文章中验证。这里AMS.startService是一个远程服务,查看AMS.startService方法。
final ActiveServices mServices; @Override public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); // Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } if (callingPackage == null) { throw new IllegalArgumentException("callingPackage cannot be null"); } if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "startService: " + service + " type=" + resolvedType); synchronized(this) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, callingPackage, userId); Binder.restoreCallingIdentity(origId); return res; } } public boolean unbindService(IServiceConnection connection) { synchronized (this) { return mServices.unbindServiceLocked(connection); } }public int bindService(IApplicationThread caller, IBinder token, Intent service, …… synchronized(this) { return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, callingPackage, userId); } } @Override public boolean stopServiceToken(ComponentName className, IBinder token, int startId) { synchronized(this) { return mServices.stopServiceTokenLocked(className, token, startId); } } @Override public int stopService(IApplicationThread caller, Intent service, String resolvedType, int userId) { …… synchronized(this) { return mServices.stopServiceLocked(caller, service, resolvedType, userId); } }
AMS通过mServices.startServiceLocked来开启服务。mServices的对象是ActiveServices,它是辅助AMS进行Service管理的类,包括Service的启动、绑定和停止。在startServiceLocked尾部调用startServiceInnerLocked方法
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, String callingPackage, final int userId) throws TransactionTooLargeException { ……return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);}
startServiceInnerLocked方法实现:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { ServiceState stracker = r.getTracker(); if (stracker != null) { stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity); } r.callStart = false; synchronized (r.stats.getBatteryStats()) { r.stats.startRunningLocked(); } String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); if (error != null) { return new ComponentName("!!", error); } if (r.startRequested && addToStarting) { boolean first = smap.mStartingBackground.size() == 0; smap.mStartingBackground.add(r); r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT; if (DEBUG_DELAYED_SERVICE) { RuntimeException here = new RuntimeException("here"); here.fillInStackTrace(); Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here); } else if (DEBUG_DELAYED_STARTS) { Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r); } if (first) { smap.rescheduleDelayedStarts(); } } else if (callerFg) { smap.ensureNotStartingBackground(r); } return r.name; }
ServiceRecord描述的是一个Service的记录,它会一直贯穿整个Service的启动过程。
/** * A running application service. */final class ServiceRecord extends Binder {static final int MAX_DELIVERY_COUNT = 3; // Maximum number of times it can fail during execution before giving up. static final int MAX_DONE_EXECUTING_COUNT = 6; final ActivityManagerService ams; final BatteryStatsImpl.Uid.Pkg.Serv stats; final ComponentName name; // service component. final String shortName; // name.flattenToShortString(). final Intent.FilterComparison intent; // original intent used to find service. final ServiceInfo serviceInfo; // all information about the service. final ApplicationInfo appInfo; // information about service's app. final int userId; // user that this service is running as final String packageName; // the package implementing intent's component final String processName; // process where this component wants to run final String permission;// permission needed to access service final boolean exported; // from ServiceInfo.exported final Runnable restarter; // used to schedule retries of starting the service final long createTime; // when this service was created ……}
startServiceInnerLocked方法并没有完成具体的启动工作,而是交给了bringUpServiceLocked方法处理。调用realStartService,开启真正的Service。
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { ……if (app != null && app.thread != null) { try { app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats); realStartServiceLocked(r, app, execInFg); return null; } catch (TransactionTooLargeException e) { throw e; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortName, e); } ……..}realStartService方法源码: private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { if (app.thread == null) { throw new RemoteException(); }…….app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState);……. sendServiceArgsLocked(r, execInFg, true);…………}private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg, boolean oomAdjusted) throws TransactionTooLargeException { final int N = r.pendingStarts.size(); if (N == 0) { return;…….r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);…….}
在realStartService方法中,app.thread通过scheduleCreateService方法来创建Service对象并调用onCreate方法,接着通过sendServiceArgsLocked方法调用Service其他方法,比如onStartCommand,这两个过程均是进程间通信。其实scheduleCreateService和sendServiceArgsLocked(该方法会调用app.thread.scheduleServiceArgs)调用逻辑基本一样,后续的源码中就只分析scheduleCreateService方法。
app.thread的对象是IApplicationThread,它的实现类是ApplicationThread,参见Activity源码分析。应此只需要查看ApplicationThread的scheduleCreateService方法。ApplicationThread是ActivityThread的内部类。
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; sendMessage(H.CREATE_SERVICE, s); } public void handleMessage(Message msg) { …….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; case BIND_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); handleBindService((BindServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break;………}
显然这里的启动过程和Activity是一样的,通过Handle H来发送消息,在handleMessage方法中通过 handleCreateService方法来创建Service。
private void handleCreateService(CreateServiceData data) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to instantiate service " + data.info.name + ": " + e.toString(), e); } } try { if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); Application app = packageInfo.makeApplication(false, mInstrumentation); service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault()); service.onCreate(); mServices.put(data.token, service); try { ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } }
handleCreateService完成了几件事:
1.通过来加载器创建了Service的实例。
2.创建Application对象,只创建一次,并调用onCreate方法(可参照Activity源码分析)。
3.创建ContextImpl对象,并通过Service方法的attach方法建立两者的关系。这个过程与Activity类似,它们都是一个Context。
4.Service调用onCreate方法,并将Service对象存储在ActivityThread的一个列表中。
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();…… service.onCreate();mServices.put(data.token, service);
Service的onCreate方法执行了,Service已经启动了。上面提到过sendServiceArgsLocked方法(app.thread.scheduleServiceArgs)最终也会通过handleServiceArgs方法调动Service的onStartCommand方法,具体内容不再详细介绍。
- Service进阶篇(startService)
- Service组件 startService() bindService()
- Service: 生命周期与 startService
- Service: 生命周期与 startService
- android service 之startService(...)
- Service之startService(二)
- Service的启动--startService
- Service启动流程-startService
- Service进阶篇(bindService)
- Activity组件之一Service--- startService
- 通过startService()方法使用Service
- Service startService方式的服务
- Service之startservice与bindservice
- Service启动方式之startService
- Service的启动(startService)
- Service启动方式之startService
- android中Service使用startService
- Android Service详解(二)---StartService
- UITableView NSIndexPath属性讲解
- GreenPlum 客户端管理工具
- MDK 小技巧
- IDEA2016 创建SpringMVC的maven项目
- 爬取网站前1_解析网站robots.txt文件
- Service进阶篇(startService)
- Python标准模块--itertools
- Google File System Google Map Reduce Google BigTable 论文
- STM8S_001_GPIO基础知识
- 用Js和CSS实现锤子手机官网海报跟随移动发生倾斜
- Mosquitto pub/sub服务实现代码浅析-主体框架
- 欢迎使用CSDN-markdown编辑器
- 编程随记:有整型数组a[],中间有连续递增的子数组,现在要求把原来数组中每个递增部分组成一个新的数组
- Cookie前后台使用乱码问题