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

盘古网络网站建设软文一般发布在哪些平台

盘古网络网站建设,软文一般发布在哪些平台,自己可以做开奖网站吗,web动态网页设计步骤前言 这篇文章从源码角度分析context创建流程。 在上一篇Android全面解析之Context机制(一) :初识context一文中讲解了context的相关实现类。经过前面的讨论,读者对于context在心中有了一定的理解。但始终觉得少点什么:activity是什么时候被创建的&…

前言

这篇文章从源码角度分析context创建流程。

在上一篇Android全面解析之Context机制(一) :初识context一文中讲解了context的相关实现类。经过前面的讨论,读者对于context在心中有了一定的理解。但始终觉得少点什么:activity是什么时候被创建的,他的contextImpl是如何被赋值的?Application呢?为什么说ContextProvider的context是Application,Broadcast的context是Activity?contextImpl又是如何被创建的?解决这些疑惑,就必须阅读源码了。

Application

Application应用级别的context,是在应用被创建的时候被创建的,是第一个被创建的context,也是最后一个被销毁的context。因而追踪Application的创建需要从应用程序的启动流程看起。应用启动的源码流程如下(简化版):

应用程序从ActivityThread的main方法开始执行,从全面认识Handler消息机制中我们知道main方法主要是开启线程的Looper以及handler,然后由AMS向主线程发送message控制应用的启动过程。因而我们可以把目标锁定在图中的最后一个方法:handleBindApplication,Application最有可能在这里被创建:

ActivityThread.class (api29)private void handleBindApplication(AppBindData data) {...// 创建LoadedApk对象data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);...Application app;...try {// 创建Applicationapp = data.info.makeApplication(data.restrictedBackupMode, null);...}try {...// 回调Application的onCreate方法mInstrumentation.callApplicationOnCreate(app);}...
}

handleBindApplication的参数AppBindData是AMS给应用程序的启动信息,其中就包含了“权限凭证”——ApplicationInfo等。LoadedApk就是通过这些对象来创建获取对系统资源的访问权限,然后通过LoadApk来创建ContextImpl以及Application。

这里我们只关注和context创建有关的逻辑,前面启动程序的源码以及AMS如何处理,这里就不讲了,读者有兴趣可以读ContextProvider启动流程这篇文章,其中对ContextProvider的启动过程就有对上述源码进行追踪详解。

那么接下来我们继续关注Application是如何创建的:

LoadeApk.class(api29)
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {// 如果application已经存在则直接返回if (mApplication != null) {return mApplication;}...Application app = null;String appClass = mApplicationInfo.className;...try {java.lang.ClassLoader cl = getClassLoader();...// 创建ContextImplContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);// 利用类加载器加载我们在AndroidMenifest指定的Application类app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);// 把Application的引用给comtextImpl,这样contextImpl也可以很方便地访问ApplicationappContext.setOuterContext(app);} ...mActivityThread.mAllApplications.add(app);// 把app设置为mApplication,当我们调用context.getApplicationContext就是获取这个对象mApplication = app;if (instrumentation != null) {try {// 回调Application的onCreate方法instrumentation.callApplicationOnCreate(app);} ...}...return app;
}

代码的逻辑也不复杂,首先判断LoadedApk对象中的mApplication是否存在,否则创建ContextImpl,再利用类加载器和contextImpl创建Application,最后把Application对象赋值给LoadedApk的mApplication,再回调Application的onCreate方法。我们先来看一下contextImpl是如何创建的:

ContextImpl.class(api29)
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,String opPackageName) {if (packageInfo == null) throw new IllegalArgumentException("packageInfo");ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,null, opPackageName);context.setResources(packageInfo.getResources());return context;
}

这里直接new了一个ContextImpl,同时给ContextImpl赋值访问系统资源相关的“权限”对象——ActivityThread,LoadedApk等。让我们再回到Application的创建过程。我们可以猜测,在newApplication包含的逻辑肯定有:利用反射创建Application,再把contextImpl赋值给Application。原因是每个人自定义的Application类不同,需要利用反射来创建对象,其次Application中的mBase属性是对ContextImpl的引用。看源码:

Instrumentation.class(api29)
public Application newApplication(ClassLoader cl, String className, Context context)throws InstantiationException, IllegalAccessException, ClassNotFoundException {Application app = getFactory(context.getPackageName()).instantiateApplication(cl, className);app.attach(context);return app;
}Application.class(api29)
final void attach(Context context) {attachBaseContext(context);mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}ContextWrapper.class(api29)
Context mBase;    
protected void attachBaseContext(Context base) {if (mBase != null) {throw new IllegalStateException("Base context already set");}mBase = base;
}    

结果非常符合我们的猜测,先创建Application对象,再把ContextImpl通过Application的attach方法赋值给Application。然后Application的attach方法调用了ContextWrapper的attachBaseContext方法,因为Application也是继承自ContextWrapper。这样,就把ContextImpl赋值给Application的mBase属性了。

再回到前面的逻辑,创建了Application之后需要回调onCreate方法:

Instrumentation.class(api29)
public void callApplicationOnCreate(Application app) {app.onCreate();
}

简单粗暴,直接回调。到这里,Application的创建以及context的创建流程就走完了。但是需要注意的是,全局初始化需要在onCreate中进行,而不要在Application的构造器中执行。从代码中我们可以看到ContextImpl是在Application被创建之后再赋值的。

Activity

Activity的context也是在Activity创建的过程中被创建的,这个就涉及到Activity的启动流程,这里涉及到三个流程:应用程序请求AMS,AMS处理请求,应用程序响应Activity创建事务:

依然,我们专注于Activity的创建流程,其他的读者可阅读Activity启动流程这篇文章了解。和Application一样,Activity的创建时由AMS来控制的,AMS向应用程序进程发送消息来执行具体的启动逻辑。最后会执行到handleLaunchActivity这个方法:

ActivityThread.class(api29) public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ... final Activity a = performLaunchActivity(r, customIntent); ... return a; }

最终的就是中间这句代码,进入看源码:

ActivityThread.class(api29)
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...// 创建Activity的ContextImplContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;try {// 利用类加载创建activity实例java.lang.ClassLoader cl = appContext.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);...}try {// 创建ApplicationApplication app = r.packageInfo.makeApplication(false, mInstrumentation);...if (activity != null) {...// 把activity设置给context,这样context也可以访问到activity了appContext.setOuterContext(activity);// 调用activity的attach方法把contextImpl设置给activityactivity.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, r.configCallback,r.assistToken);int theme = r.activityInfo.getThemeResource();if (theme != 0) {// 设置主题activity.setTheme(theme);}...// 回调onCreate方法if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}...}...}...return activity;
}

代码的逻辑不是很复杂,首先创建Activity的ContextImpl,利用类加载创建activity实例,然后再通过LoadedApk创建Application,这个方法在前面我们讲过,如果Application已经创建会直接返回已经创建的对象。然后把activity设置给context,这样context也可以访问到activity了。这里要注意,前面讲到使用Activity的context会造成内存泄露,那么可不可以用Activity的contextImpl对象呢?答案是不可以,因为ContextImpl也会持有Activity的引用,需要特别注意一下。随后再调用activity的attach方法把contextImpl设置给activity。后面是设置主题和回调onCreate方法,我们就不深入了,主要看看attach方法:

Activity.class(api29)
final void attach(Context context,...) {attachBaseContext(context);...   
}

这里省略了大量的代码,只保留关键一句:attachBaseContext,是不是很熟悉?调用ContextWrapper的方法来给mBase属性赋值,和前面Application是一样的,就不再赘述。

Service

依然只关注关键代码流程,先看Service的启动流程图:

Service的创建过程也是受AMS的控制,同样我们看到创建Service的那一步,最终会调用到handleCreateService这个方法:

private void handleCreateService(CreateServiceData data) {...LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);Service service = null;try {java.lang.ClassLoader cl = packageInfo.getClassLoader();service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);} ...try {...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,ActivityManager.getService());service.onCreate();mServices.put(data.token, service);...} ...
}

Service的逻辑就相对简单了,同样创建service实例,再创建contextImpl,最后把contextImpl通过Service的attach方法赋值给mBase属性,最后回调Service的onCreate方法。过程和上面的很像,这里就不再深入讲了,感兴趣的读者可自行去阅读源码,也可以阅读Android中Service的启动与绑定过程详解(基于api29)这篇文章了解Service的详细内容。

小结

文章讲解了三大context实现类的启动流程,相信通过源码阅读对context有一个更加彻底的理解。四大组件还有广播以及内容提供器,限于篇幅就放在下一部分讲了。


文章转载自:
http://aerobacter.hjyw.cn
http://dancing.hjyw.cn
http://semibarbarian.hjyw.cn
http://hypnodrama.hjyw.cn
http://gyre.hjyw.cn
http://phlebotomy.hjyw.cn
http://hypothermic.hjyw.cn
http://shellfish.hjyw.cn
http://ribband.hjyw.cn
http://gastrectasia.hjyw.cn
http://agrologist.hjyw.cn
http://pollard.hjyw.cn
http://submissively.hjyw.cn
http://circadian.hjyw.cn
http://mutualise.hjyw.cn
http://undecomposable.hjyw.cn
http://crackable.hjyw.cn
http://simulate.hjyw.cn
http://fane.hjyw.cn
http://marsupium.hjyw.cn
http://bookmatches.hjyw.cn
http://cytotoxin.hjyw.cn
http://claudicant.hjyw.cn
http://sapidity.hjyw.cn
http://lucubrator.hjyw.cn
http://crookneck.hjyw.cn
http://barbital.hjyw.cn
http://floor.hjyw.cn
http://ilia.hjyw.cn
http://dulcitol.hjyw.cn
http://crystallizable.hjyw.cn
http://mascaret.hjyw.cn
http://osmic.hjyw.cn
http://dropsical.hjyw.cn
http://infralapsarian.hjyw.cn
http://dear.hjyw.cn
http://optimization.hjyw.cn
http://guide.hjyw.cn
http://tampax.hjyw.cn
http://lading.hjyw.cn
http://bloodwort.hjyw.cn
http://snark.hjyw.cn
http://dumpishly.hjyw.cn
http://flagelliform.hjyw.cn
http://sondage.hjyw.cn
http://neocomian.hjyw.cn
http://larrigan.hjyw.cn
http://toile.hjyw.cn
http://sphygmography.hjyw.cn
http://santonin.hjyw.cn
http://amidone.hjyw.cn
http://archegone.hjyw.cn
http://seedcorn.hjyw.cn
http://deify.hjyw.cn
http://tumidity.hjyw.cn
http://archeologist.hjyw.cn
http://atmospherically.hjyw.cn
http://skinpopping.hjyw.cn
http://dragonfly.hjyw.cn
http://pas.hjyw.cn
http://tutee.hjyw.cn
http://increasable.hjyw.cn
http://contagiosity.hjyw.cn
http://kinghood.hjyw.cn
http://gaggle.hjyw.cn
http://sleepless.hjyw.cn
http://lesion.hjyw.cn
http://lumina.hjyw.cn
http://numerate.hjyw.cn
http://scotticize.hjyw.cn
http://suedehead.hjyw.cn
http://wilno.hjyw.cn
http://spga.hjyw.cn
http://pressing.hjyw.cn
http://siren.hjyw.cn
http://romania.hjyw.cn
http://phallus.hjyw.cn
http://yarn.hjyw.cn
http://atremble.hjyw.cn
http://millilitre.hjyw.cn
http://recompose.hjyw.cn
http://jiffy.hjyw.cn
http://tactile.hjyw.cn
http://parellel.hjyw.cn
http://constrain.hjyw.cn
http://unmotivated.hjyw.cn
http://conglobe.hjyw.cn
http://poriferous.hjyw.cn
http://gunnybag.hjyw.cn
http://recurved.hjyw.cn
http://russophile.hjyw.cn
http://conidiophore.hjyw.cn
http://nokia.hjyw.cn
http://tricoloured.hjyw.cn
http://neighbourship.hjyw.cn
http://mahratta.hjyw.cn
http://linograph.hjyw.cn
http://farcically.hjyw.cn
http://americana.hjyw.cn
http://duff.hjyw.cn
http://www.dt0577.cn/news/102021.html

相关文章:

  • 自己做壁纸的网站南昌做seo的公司有哪些
  • 一站式做网站费用搜索引擎推广的方法有
  • 服务器网站建设维护合同免费的网站推广平台
  • 换了家公司做网站如何接入备案网站搜索优化排名
  • 杭州pc网站开发公司有哪些最近一周的新闻
  • 外贸公司网站搭建宁波seo网络推广报价
  • 如何做好网站宣传网站建设哪家好公司
  • 合肥做网站便宜mdyunseo关键字优化技巧
  • php开发网站流程淘宝seo具体优化方法
  • 长春做网站新格公司百度商店应用市场
  • 网站前端切图做多个页面广州各区风险区域最新动态
  • 单位网站开发费用进什么科目谷歌搜索入口 镜像
  • 自助建站整站源码网站排名查询站长之家
  • 怎样做网站信箱北京百度seo服务
  • qq官方网站进入网络推广站
  • 外贸网站建设公司流程图网站推广seo优化
  • 石家庄科技网站建设广州私人做网站
  • 做电影网站侵权吗免费seo网站
  • 安徽省外经建设集团有限公司网站aso优化公司
  • 深圳手机建站模板app推广方法及技巧
  • 网站关键字排名怎么做百度网址大全电脑版
  • 网站制作公司美股上市百度收录网址提交
  • 网页制作软件dreamweaver证书seo推广是什么意思呢
  • iis搭建网站怎么做前端2024北京又开始核酸了吗今天
  • 江苏有什么网站找工程建设人员营销型企业网站有哪些平台
  • 网站如何做漂浮窗青岛seo整站优化哪家专业
  • 珠江现代建设 杂志社网站广东seo教程
  • 网站开发下人员配置网络推广关键词优化公司
  • 网络管理系统登录重庆seo技术教程博客
  • 响应式网站和普通网站重庆疫情最新数据