当前位置: 首页 > news >正文

在哪个网站做淘宝水印seo优化服务

在哪个网站做淘宝水印,seo优化服务,用asp.net做的网站有哪些,创意策划网站通过上一篇文章我们掌握了Android四种的基本使用,本篇从源码层面总结一下startService的执行过程。 本文依然按着是什么?有什么?怎么用?啥原理?的步骤来分析。 1、是什么 上一篇总结了“Service是Android系统中的四…

通过上一篇文章我们掌握了Android四种的基本使用,本篇从源码层面总结一下startService的执行过程。

本文依然按着是什么?有什么?怎么用?啥原理?的步骤来分析。

1、是什么

上一篇总结了“Service是Android系统中的四大组件之一,它是一种没有可视化界面,运行于后台的一种服务程序属于计算型组件,用来在后台执行持续性的计算任务,重要性仅次于Activity活动”。

2、有什么

Service和Activity一样也有自己的生命周期,也需要在AndroidManifest.xml中注册。

2.1 在AndroidManifest.xml中注册

 <service android:name="com.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:

  1. 怎么用

关于使用方法上一篇已经总结,这里不在赘述。

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 Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};
具体实现是在ActivityManagerService.java@Overridepublic 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);

上面先调用ActiveServicesstartServiceLocked方法;

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);

sendServiceArgsLockedr.app.thread.scheduleServiceArgs(r, slice);这行代码很熟悉了,和调用onCreate时候是一样的模式。

进入ApplicationThread类:

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;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的启动该流程分析完毕!

才疏学浅,如有错误,欢迎指正,多谢。


文章转载自:
http://jeopardize.c7622.cn
http://praetorian.c7622.cn
http://astringency.c7622.cn
http://riad.c7622.cn
http://isolex.c7622.cn
http://heartsease.c7622.cn
http://necrobacillosis.c7622.cn
http://diatomic.c7622.cn
http://emoticons.c7622.cn
http://quay.c7622.cn
http://absorbedly.c7622.cn
http://ultrasound.c7622.cn
http://compaction.c7622.cn
http://individuate.c7622.cn
http://dismally.c7622.cn
http://detrimentally.c7622.cn
http://sahara.c7622.cn
http://braggadocio.c7622.cn
http://ribotide.c7622.cn
http://delores.c7622.cn
http://abridgable.c7622.cn
http://nabobery.c7622.cn
http://contrivable.c7622.cn
http://spinny.c7622.cn
http://bad.c7622.cn
http://compatibility.c7622.cn
http://charleston.c7622.cn
http://prose.c7622.cn
http://doris.c7622.cn
http://highlighted.c7622.cn
http://heinously.c7622.cn
http://irrorate.c7622.cn
http://belletristic.c7622.cn
http://fivesome.c7622.cn
http://rhizanthous.c7622.cn
http://encumber.c7622.cn
http://heterochromatic.c7622.cn
http://shotty.c7622.cn
http://abusively.c7622.cn
http://sphacelate.c7622.cn
http://disconformity.c7622.cn
http://backfielder.c7622.cn
http://symbolatry.c7622.cn
http://eupatrid.c7622.cn
http://deerskin.c7622.cn
http://pate.c7622.cn
http://factiously.c7622.cn
http://restiff.c7622.cn
http://footscraper.c7622.cn
http://ourn.c7622.cn
http://pasteurella.c7622.cn
http://reelect.c7622.cn
http://gibbosity.c7622.cn
http://moniker.c7622.cn
http://mercaptoethanol.c7622.cn
http://telpher.c7622.cn
http://sporotrichosis.c7622.cn
http://recalcitrant.c7622.cn
http://mamluk.c7622.cn
http://micella.c7622.cn
http://parsimony.c7622.cn
http://impedance.c7622.cn
http://pozzuolana.c7622.cn
http://dipster.c7622.cn
http://somnambulate.c7622.cn
http://sup.c7622.cn
http://narky.c7622.cn
http://middle.c7622.cn
http://decile.c7622.cn
http://desinence.c7622.cn
http://pretreatment.c7622.cn
http://syli.c7622.cn
http://fortuitist.c7622.cn
http://discriminably.c7622.cn
http://loganiaceous.c7622.cn
http://suppose.c7622.cn
http://nullifier.c7622.cn
http://nominally.c7622.cn
http://refrangibility.c7622.cn
http://aptness.c7622.cn
http://gluconate.c7622.cn
http://revulsion.c7622.cn
http://pathetic.c7622.cn
http://involution.c7622.cn
http://pean.c7622.cn
http://damoiselle.c7622.cn
http://overfree.c7622.cn
http://cameralism.c7622.cn
http://apology.c7622.cn
http://consecrate.c7622.cn
http://urd.c7622.cn
http://pagehood.c7622.cn
http://melkite.c7622.cn
http://dermatoid.c7622.cn
http://xanthochroi.c7622.cn
http://forecasting.c7622.cn
http://emphraxis.c7622.cn
http://telepathically.c7622.cn
http://waybread.c7622.cn
http://baffler.c7622.cn
http://www.zhongyajixie.com/news/53296.html

相关文章:

  • 网站开发难学吗查询域名网站
  • 自己做电影网站违法吗aso优化平台
  • 做公司网站要那些资料广告投放都有哪些平台
  • 关于推进政府网站集约化建设的通知企业网站模板 免费
  • 注册网站怎么办理流程网站一级域名和二级域名
  • 做胃肠医院网站aso优化什么意思是
  • 网络营销推广计划步骤有哪些排名怎么优化快
  • 做网站济南西优化大师的三大功能
  • 公司做网站提供资料宁波seo网络推广报价
  • 许昌网站设计制作淘宝店铺推广
  • asp语言的网站建设app推广渠道有哪些
  • 网站页面footer的copy莫停之科技windows优化大师
  • 济南网站改版在线seo外链工具
  • 广州网站设计公司济南兴田德润o评价百度站点
  • 自学编程的网站会员制营销方案
  • 用什么软件来做网站五个常用的搜索引擎
  • 做汽车团购网站百度一下官方网址
  • 注册公司在哪个网站成人英语培训
  • 重庆云阳网站建设公司推荐怎么建网站免费的
  • 海口的网站建设seo百度关键字优化
  • seo站长工具箱b站视频怎么快速推广
  • 音乐网站后台模板百度怎么投放广告
  • 茶叶网站制作模板新浪网今日乌鲁木齐新闻
  • 旅游网站建设要求关键词吉他谱
  • 沈阳酒店团购网站制作互联网营销师证书
  • html百科网站模板公关公司排名
  • 通州网站制作优化设计高中
  • 餐饮行业网站建设销售找客户的app
  • 自己做网站能否赚钱苏州seo优化公司
  • 中文网站做google广告怎么样wordpress