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

凤凰网新冠肺炎疫情实时动态/杭州企业seo

凤凰网新冠肺炎疫情实时动态,杭州企业seo,网站建设做网站,上海哪里有网站建设前言 此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程。建议阅读此篇文章前,请先阅读Android深入四大组件(一)应用程序启动过程&#xf…

前言

此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程。建议阅读此篇文章前,请先阅读Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章。

1.ContextImpl到ActivityManageService的调用过程

要启动Service,我们会调用startService方法,它的实现在ContextWrapper中,代码如下所示。
frameworks/base/core/java/android/content/ContextWrapper.java

public class ContextWrapper extends Context {Context mBase;
...@Overridepublic ComponentName startService(Intent service) {return mBase.startService(service);}
...    
}复制代码

在startService方法中会调用mBase的startService方法,Context类型的mBase对象具体指的是什么呢?在Android深入四大组件(一)应用程序启动过程(后篇)这篇文章中我们讲过ActivityThread启动Activity时会调用如下代码创建Activity的上下文环境。
frameworks/base/core/java/android/app/ActivityThread.java

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...if (activity != null) {Context appContext = createBaseContextForActivity(r, activity);//1...}activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window);...}return activity;
}复制代码

在注释1处创建上下文对象appContext ,并传入Activity的attach方法中,将Activity与上下文对象appContext 关联起来,这个上下文对象appContext 的具体类型是什么,我们接着查看createBaseContextForActivity方法,代码如下所示。
frameworks/base/core/java/android/app/ActivityThread.java

private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
...ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token, displayId, r.overrideConfig);appContext.setOuterContext(activity);Context baseContext = appContext;...return baseContext;
}复制代码

这里可以得出结论,上下文对象appContext 的具体类型就是ContextImpl 。Activity的attach方法中将ContextImpl赋值给ContextWrapper的成员变量mBase中,因此,mBase具体指向就是ContextImpl 。
那么,我们紧接着来查看ContextImpl的startService方法,代码如下所示。
frameworks/base/core/java/android/app/ContextImpl.java

Override
public ComponentName startService(Intent service) {warnIfCallingFromSystemProcess();return startServiceCommon(service, mUser);
}private ComponentName startServiceCommon(Intent service, UserHandle user) {try {validateServiceIntent(service);service.prepareToLeaveProcess(this);/*** 1*/ComponentName cn = ActivityManagerNative.getDefault().startService(mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), getOpPackageName(), user.getIdentifier());...return cn;} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}复制代码

startService方法中会return startServiceCommon方法,在startServiceCommon方法中会在注释1处调用ActivityManageService(AMS)的代理对象ActivityManagerProxy(AMP)的startService方法,最终会调用AMS的startService方法。至于注释1处的代码为何会调用AMS的startService方法,在Android深入四大组件(一)应用程序启动过程(前篇)这篇文章中已经讲过,这里不再赘述。
ContextImpl到ActivityManageService的调用过程如下面的时序图所示。

2.ActivityThread启动Service

我们接着来查看AMS的startService方法。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

Override
public ComponentName startService(IApplicationThread caller, Intent service,String resolvedType, String callingPackage, int userId)throws TransactionTooLargeException {...synchronized(this) {...ComponentName res = mServices.startServiceLocked(caller, service,resolvedType, callingPid, callingUid, callingPackage, userId);//1Binder.restoreCallingIdentity(origId);return res;}
}复制代码

注释1处调用mServices的startServiceLocked方法,mServices的类型是ActiveServices,ActiveServices的startServiceLocked方法代码如下所示。
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

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);}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;}复制代码

startServiceLocked方法的末尾return了startServiceInnerLocked方法,而startServiceInnerLocked方法中又调用了bringUpServiceLocked方法:
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

  private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,boolean whileRestarting, boolean permissionsReviewRequired)throws TransactionTooLargeException {
...final String procName = r.processName;//1ProcessRecord app;if (!isolated) {app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);//2if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid+ " app=" + app);if (app != null && app.thread != null) {//3try {app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);realStartServiceLocked(r, app, execInFg);//4return null;} catch (TransactionTooLargeException e) {throw e;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting service " + r.shortName, e);}}} else {app = r.isolatedProc;}if (app == null && !permissionsReviewRequired) {//5if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,"service", r.name, false, isolated, false)) == null) {//6...}if (isolated) {r.isolatedProc = app;}}...     
}复制代码

在注释1处得到ServiceRecord的processName的值赋值给procName ,其中ServiceRecord用来描述Service的android:process属性。注释2处将procName和Service的uid传入到AMS的getProcessRecordLocked方法中,来查询是否存在一个与Service对应的ProcessRecord类型的对象app,ProcessRecord主要用来记录运行的应用程序进程的信息。注释5处判断Service对应的app为null则说明用来运行Service的应用程序进程不存在,则调用注释5处的AMS的startProcessLocked方法来创建对应的应用程序进程。关于创建应用程序进程请查看Android应用程序进程启动过程(前篇) 和Android应用程序进程启动过程(后篇)这两篇文章。注释3处判断如果用来运行Service的应用程序进程存在,则调用注释4处的realStartServiceLocked方法:

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) throws RemoteException {...try {...app.thread.scheduleCreateService(r, r.serviceInfo,mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState);r.postNotification();created = true;} catch (DeadObjectException e) {...} ...
}复制代码

在realStartServiceLocked方法中调用了app.thread的scheduleCreateService方法。其中app.thread是IApplicationThread类型的,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。ApplicationThread的scheduleCreateService方法如下所示。
frameworks/base/core/java/android/app/ActivityThread.java

   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);}复制代码

首先将要启动的信息封装成CreateServiceData 对象并传给sendMessage方法,sendMessage方法向H发送CREATE_SERVICE消息,H是ActivityThread的内部类并继承Handler。这个过程和应用程序的启动过程(根Activity启动过程)是类似的。我们接着查看H的handleMessage方法。
frameworks/base/core/java/android/app/ActivityThread.java

  public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));switch (msg.what) {...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;...}...}...   }复制代码

handleMessage方法根据消息类型,调用了handleCreateService方法:

frameworks/base/core/java/android/app/ActivityThread.java

 private void handleCreateService(CreateServiceData data) {unscheduleGcIdler();LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);//1Service service = null;try {java.lang.ClassLoader cl = packageInfo.getClassLoader();//2service = (Service) cl.loadClass(data.info.name).newInstance();//3} catch (Exception e) {...}}try {if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);ContextImpl context = ContextImpl.createAppContext(this, packageInfo);//4context.setOuterContext(service);Application app = packageInfo.makeApplication(false, mInstrumentation);service.attach(context, this, data.info.name, data.token, app,ActivityManagerNative.getDefault());//5service.onCreate();//6mServices.put(data.token, service);//7...} catch (Exception e) {...}}复制代码

注释1处获取要启动Service的应用程序的LoadedApk,LoadedApk是一个APK文件的描述类。注释2处通过调用LoadedApk的getClassLoader方法来获取类加载器。接着在注释3处根据CreateServiceData对象中存储的Service信息,将Service加载到内存中。注释4处创建Service的上下文环境ContextImpl对象。注释5处通过Service的attach方法来初始化Service。注释6处调用Service的onCreate方法,这样Service就启动了。在注释7处将启动的Service加入到ActivityThread的成员变量mServices中,其中mServices是ArrayMap类型。
最后给出这一节的时序图。

http://www.lbrq.cn/news/806653.html

相关文章:

  • 做自己的首席安全官的网站/cms
  • 接做施工图的网站/百度站长联盟
  • 用wang域名做购物网站怎么样/进入百度官网
  • 电子商城网站开发价格/google 官网入口
  • 做网站绑定 对应的域名/渠道推广有哪些方式
  • 有创意做网站找投资/网络营销的五大特点
  • 百度做的网站 后台管理怎么进入/中央常委成员名单
  • 杭州建委网站首页/长春网站公司哪家好
  • 上海做网站哪家好/百度关键词推广公司哪家好
  • 嘉鱼网站建设哪家专业/电商代运营公司
  • 南部网站建设/西安网站建设公司排行榜
  • 做字体的网站/本地推广最好用的平台
  • 找公司做网站源代码给客户吗/济南seo官网优化
  • 做网站等保收费/汽车推广软文
  • 电视网站后台管理系统漏洞/seo优化一般多少钱
  • 查询网站服务商/百度站长平台工具
  • wordpress的wp后台css样式错乱/北京关键词优化平台
  • 上海高端网站定制建设公司/临沂seo排名外包
  • 手机直播app开发制作/关键词优化一般收费价格
  • 做网站使用字体图标/线上营销工具
  • 网络舆情现状分析/seo网站关键词
  • 贵州网站设计/山东搜索引擎优化
  • 泰康人寿保险官方网站/企业seo推广
  • 男人做鸭子的网站/十堰seo排名公司
  • 营销型网站建设合同/杭州关键词自动排名
  • 16年百度对泛解析网站的惩罚/上海seo外包公司
  • 也买酒技术网站建设/seo静态页源码
  • 网络销售怎么做网站/2023年重大时政热点
  • 男女做羞羞事的网站/站长工具如何使用
  • 成都网站制作怎么样/阿里云搜索引擎
  • ansible简单playbook剧本例子2
  • RabbitMQ的特点和消息可靠性保障
  • 【力扣】面试经典150题总结01-数组/字符串
  • 进程控制:从创建到终结的完整指南
  • Django自带的加密算法
  • 对于ui=f(state)的理解(react)