做论坛网站如何赚钱的,wordpress连接ftp,建立健全,西安搬家公司哪家服务好还实惠通过上一篇文章我们掌握了Android四种的基本使用#xff0c;本篇从源码层面总结一下startService的执行过程。
本文依然按着是什么#xff1f;有什么#xff1f;怎么用#xff1f;啥原理#xff1f;的步骤来分析。
1、是什么
上一篇总结了“Service是Android系统中的四…通过上一篇文章我们掌握了Android四种的基本使用本篇从源码层面总结一下startService的执行过程。
本文依然按着是什么有什么怎么用啥原理的步骤来分析。
1、是什么
上一篇总结了“Service是Android系统中的四大组件之一它是一种没有可视化界面运行于后台的一种服务程序。属于计算型组件用来在后台执行持续性的计算任务重要性仅次于Activity活动”。
2、有什么
Service和Activity一样也有自己的生命周期也需要在AndroidManifest.xml中注册。
2.1 在AndroidManifest.xml中注册 service android:namecom.example.testdemo.service.ServiceJia /
2.2 Service生命周期
Service的生命周期有很多本文只谈startService和stopService涉及到的。
onCreate
它只在Service刚被创建的时刻被调用Service在运行中这个方法将不会被调用。也就是只有经历过onDestroy生命周期以后再次startService(intent) 才会执行。
onStartCommand
OnStartCommand方法是最重要的方法因为它在我们需要启动Service的时候被调用。形参时当初startService时传递进来的Intent这样就可以给Service传值。在这个方法中可以做服务启动后要执行的任务但是切记这里也是在主线程运行耗时的操作必须创建一个子线程来执行否则可能引发ANR导致程序闪退。
关于onStartCommand的返回值介绍
START_STICKY此时Service被杀死以后将会被重新创建。但是不会重新传入原来的Intent对象而是传入intent为null。
START_NOT_STICKY此时Service被杀死以后不会被重新创建。
START_REDELIVER_INTENT功能与START_STICKY类似在Service被杀死以后将会被重新创建。厉害的一点时该返回值时Intent会重新传递给Service。 onDestroy
onDestory是在Service即将被销毁时执行的生命名周期Service和Activity生命周期不一样Service没有onStop生命周期。 日志打印
调用startService后的生命周期2024-07-01 10:20:59.756 20505-20505/com.example.testdemo3 E/com.example.testdemo3.service.ServiceJia: onCreate:2024-07-01 10:20:59.757 20505-20505/com.example.testdemo3 E/com.example.testdemo3.service.ServiceJia: onStartCommand:
调用stopService后的生命周期2024-07-01 10:21:06.861 20505-20505/com.example.testdemo3 E/com.example.testdemo3.service.ServiceJia: onDestroy: 怎么用
关于使用方法上一篇已经总结这里不在赘述。
4、啥原理
Service的启动方法是调用
Intent serviceIntent new Intent(ServiceActivity.this, ServiceJia.class);startService(serviceIntent);
然后我们顺着startService方法开始解析源码SDK版本API 30
4.1 从ContexWrapper的startService开始
Override
public ComponentName startService(Intent service) {return mBase.startService(service);
}
4.2 ContextImpl类startService
mBase的类型是Context但实际代码逻辑是在它的实现类ContextImpl类。 Overridepublic 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);ComponentName cn ActivityManager.getService().startService(mMainThread.getApplicationThread(), service,service.resolveTypeIfNeeded(getContentResolver()), requireForeground,getOpPackageName(), getAttributionTag(), 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());} else if (cn.getPackageName().equals(?)) {throw new IllegalStateException(Not allowed to start service service : cn.getClassName());}}return cn;} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
在ContextImpl类的startService中调用了startServiceCommon方法而其中的关键代码是ActivityManager.getService().startService方法调用。
4.3 来到ActivityManager类 /*** hide*/UnsupportedAppUsagepublic static IActivityManager getService() {return IActivityManagerSingleton.get();}UnsupportedAppUsageprivate static final SingletonIActivityManager IActivityManagerSingleton new SingletonIActivityManager() {Overrideprotected IActivityManager create() {final IBinder b ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am IActivityManager.Stub.asInterface(b);return am;}};
具体实现是在ActivityManagerService.javaOverridepublic ComponentName startService(IApplicationThread caller, Intent service,String resolvedType, boolean requireForeground, String callingPackage,String callingFeatureId, int userId)throws TransactionTooLargeException {enforceNotIsolatedCaller(startService);// Refuse possible leaked file descriptorsif (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 fg requireForeground);synchronized(this) {final int callingPid Binder.getCallingPid();final int callingUid Binder.getCallingUid();final long origId Binder.clearCallingIdentity();ComponentName res;try {res mServices.startServiceLocked(caller, service,resolvedType, callingPid, callingUid,requireForeground, callingPackage, callingFeatureId, userId);} finally {Binder.restoreCallingIdentity(origId);}return res;}
}
4.4 进入ActiveServices类用来辅助ActivityServiceManager管理Service的启动和停止等。
mServices new ActiveServices(this);
上面先调用ActiveServices的startServiceLocked方法
res mServices.startServiceLocked(caller, service,resolvedType, callingPid, callingUid,requireForeground, callingPackage, callingFeatureId, userId);
然后startServiceLocked又调用本类的startServiceInnerLocked方法
ComponentName cmp startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
然后startServiceInnerLocked又调用本类的bringUpServiceLocked方法
String error bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
然后在调用bringUpServiceLocked方法realStartServiceLocked
realStartServiceLocked(r, app, execInFg);
4.5调用ApplicationThread的scheduleCreateService方法
app.thread.scheduleCreateService(r, r.serviceInfo,mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),app.getReportedProcState());
之后调用了sendServiceArgsLocked(r, execInFg, true);他就是onStartCommand生命周期此处伏笔下面4.8中详聊。
4.6 进入ApplicationThread类 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);}
这里sendMessage方法不是Handler的哈是封装以后的继续看 void sendMessage(int what, Object obj) {sendMessage(what, obj, 0, 0, false);
}private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {if (DEBUG_MESSAGES) {Slog.v(TAG,SCHEDULE what mH.codeToString(what) : arg1 / obj);}Message msg Message.obtain();msg.what what;msg.obj obj;msg.arg1 arg1;msg.arg2 arg2;if (async) {msg.setAsynchronous(true);}mH.sendMessage(msg);}
4.7 这里发送了消息然后去找对应what H.CREATE_SERVICE的处理
在handleMessage方法中处理case CREATE_SERVICE:if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,(serviceCreate: String.valueOf(msg.obj)));}handleCreateService((CreateServiceData)msg.obj);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;
关键时刻来咯
UnsupportedAppUsageprivate 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 {if (localLOGV) Slog.v(TAG, Creating service data.info.name);ContextImpl context ContextImpl.createAppContext(this, packageInfo);Application app packageInfo.makeApplication(false, mInstrumentation);java.lang.ClassLoader cl packageInfo.getClassLoader();service packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);// Service resources must be initialized with the same loaders as the application// context.context.getResources().addLoaders(app.getResources().getLoaders().toArray(new ResourcesLoader[0]));context.setOuterContext(service);service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());service.onCreate();mServices.put(data.token, service);try {ActivityManager.getService().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);}}}
这里先创建了一个ContextImpl实例然后创建了Application这里是个工厂模式等于空了才创建创建Service实例并与ContextImpl关联然后调用onCreate的生命周期方法。最后有个mServices.put后面其他场景会从里面取来使用。
4.8再看onStartCommand生命周期
先生是否记得上面4.4小节买过伏笔sendServiceArgsLocked(r, execInFg, true);
sendServiceArgsLocked的r.app.thread.scheduleServiceArgs(r, slice);这行代码很熟悉了和调用onCreate时候是一样的模式。
进入ApplicationThread类
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {ListServiceStartArgs 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;sendMessage(H.SERVICE_ARGS, s);}}
二次封装的发消息
sendMessage(H.SERVICE_ARGS, s);和onCreate一样。
handleMessage处理消息
case SERVICE_ARGS:if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,(serviceStart: String.valueOf(msg.obj)));}handleServiceArgs((ServiceArgsData)msg.obj);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;
从mServices取出onCreate是存的service然后调用onStartCommand生命周期。
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) {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) {if (!mInstrumentation.onException(s, e)) {throw new RuntimeException(Unable to start service s with data.args : e.toString(), e);}}}}
至此StartService的启动该流程分析完毕
才疏学浅如有错误欢迎指正多谢。