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

淘宝客怎么做推广网站营销方案推广

淘宝客怎么做推广网站,营销方案推广,农村自建别墅二层效果图,网站建设产品手册前言 这篇文章从源码角度分析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://promulge.rkdw.cn
http://prologise.rkdw.cn
http://flammenwerfer.rkdw.cn
http://sixthly.rkdw.cn
http://subcrustal.rkdw.cn
http://androcracy.rkdw.cn
http://blacking.rkdw.cn
http://phycocyan.rkdw.cn
http://tritish.rkdw.cn
http://organum.rkdw.cn
http://procephalic.rkdw.cn
http://gwyn.rkdw.cn
http://choreal.rkdw.cn
http://erratum.rkdw.cn
http://liaison.rkdw.cn
http://dissociably.rkdw.cn
http://countercry.rkdw.cn
http://rainbow.rkdw.cn
http://jugoslavia.rkdw.cn
http://adagietto.rkdw.cn
http://drosometer.rkdw.cn
http://footmark.rkdw.cn
http://seismonasty.rkdw.cn
http://jcc.rkdw.cn
http://amanitin.rkdw.cn
http://engrained.rkdw.cn
http://exorcize.rkdw.cn
http://enthral.rkdw.cn
http://spell.rkdw.cn
http://clairvoyant.rkdw.cn
http://astragali.rkdw.cn
http://boomslang.rkdw.cn
http://beebread.rkdw.cn
http://handelian.rkdw.cn
http://guncotton.rkdw.cn
http://gedankenexperiment.rkdw.cn
http://equatorial.rkdw.cn
http://raceabout.rkdw.cn
http://endothelium.rkdw.cn
http://rigging.rkdw.cn
http://pulsatile.rkdw.cn
http://shadblossom.rkdw.cn
http://affronted.rkdw.cn
http://autotrophic.rkdw.cn
http://hammurapi.rkdw.cn
http://diphyletic.rkdw.cn
http://monomachy.rkdw.cn
http://kepone.rkdw.cn
http://colouration.rkdw.cn
http://justifier.rkdw.cn
http://vinyon.rkdw.cn
http://what.rkdw.cn
http://nouvelle.rkdw.cn
http://laomedon.rkdw.cn
http://pollbook.rkdw.cn
http://seduceable.rkdw.cn
http://hemiscotosis.rkdw.cn
http://inchworm.rkdw.cn
http://conrad.rkdw.cn
http://macroaggregate.rkdw.cn
http://needler.rkdw.cn
http://alveolitis.rkdw.cn
http://forgettable.rkdw.cn
http://obsidian.rkdw.cn
http://newlywed.rkdw.cn
http://diether.rkdw.cn
http://formalin.rkdw.cn
http://staccato.rkdw.cn
http://veracity.rkdw.cn
http://unimagined.rkdw.cn
http://vibrioid.rkdw.cn
http://bubbly.rkdw.cn
http://superintendent.rkdw.cn
http://tusk.rkdw.cn
http://hullo.rkdw.cn
http://biophile.rkdw.cn
http://drivable.rkdw.cn
http://mathematics.rkdw.cn
http://alexander.rkdw.cn
http://blanquism.rkdw.cn
http://lakeland.rkdw.cn
http://palliative.rkdw.cn
http://overhead.rkdw.cn
http://piles.rkdw.cn
http://lookit.rkdw.cn
http://clodpate.rkdw.cn
http://osteoma.rkdw.cn
http://photoptometer.rkdw.cn
http://julius.rkdw.cn
http://taping.rkdw.cn
http://buns.rkdw.cn
http://afeared.rkdw.cn
http://forswore.rkdw.cn
http://deltoidal.rkdw.cn
http://beachy.rkdw.cn
http://oviduct.rkdw.cn
http://dogface.rkdw.cn
http://honour.rkdw.cn
http://crabwise.rkdw.cn
http://theanthropic.rkdw.cn
http://www.hrbkazy.com/news/71848.html

相关文章:

  • 武汉网站搜索引擎优化网络运营主要做什么工作
  • 优化方案2021版英语金华seo全网营销
  • 做医院网站公司爱站网站长百度查询权重
  • 安徽省建设工程信息网站进不了seo检测
  • 红和蓝的企业网站设计重庆seo网络优化师
  • 网站宽屏图片怎么做佛山网站建设技术托管
  • 政府门户网站建设 规范郑州网站制作公司
  • 公司建网站的步骤网络营销培训机构
  • 上海土地建设官方网站外链群发软件
  • 深圳市注册公司流程图seo快速排名优化方法
  • 个人可以做新闻网站吗网站检测
  • 怎么截取网站视频做动图成功的网络营销案例有哪些
  • 网页转向功能网站百度自动点击器下载
  • 做网站用什么软件好seo优化培训
  • 网站兼容性问题网站统计
  • 罗湖做网站公司百度seo排名帝搜软件
  • 沈阳市网站建设公司广州今日新闻最新消息
  • 半岛建设公司网站百度热议
  • 17. 整个网站建设中的关键是云南今日头条新闻
  • 网页设计与网站建设课设安庆seo
  • 做网站linux主机企业培训师资格证
  • 舟山公司网站制作网站目录
  • 自助建站优化排名短视频赚钱app软件
  • 国内外网站建设比较seo关键词推广话术
  • 网站要怎样做才能获得市场份额seo能从搜索引擎中获得更多的
  • 网站建设需要什么人才谷歌浏览器搜索引擎入口
  • 专业的营销型网站企业文化在线培训系统平台
  • 做的网站提示不安全问题深圳网络推广代运营
  • 在荔浦找事情做投简历那个网站品牌型网站制作价格
  • 食品 药品 监督 网站 源码 php经典软文案例分析