热点资讯
软件开发公司 深刻理会Android App设备中Context的用法
发布日期:2024-07-16 15:33 点击次数:228
Context在设备Android诳骗的过程中饰演着非常进击的变装,比如启动一个Activity需要使用context.startActivity活动,将一个xml文献疗养为一个View对象也需要使用Context对象,不错这样说,离开了这个类,Android设备寸步难行,对于这样一个类,咱们又对他了解若干呢。我就说说我的感受吧,在刚脱手学习Android设备时,嗅觉使用Context的处所一直即是传入一个Activity对象软件开发公司,久而久之嗅觉只淌若Context的处所就传入一个Activity就行了,那么咱们当今就来详备的分析一下Context和Activity的干系吧! 在脱手本文之前咱们先搁置一个问题在这里: 咱们普通在取得技俩资源时使用context.getResources()的时分为什么放回的是统一个值,明明是使用不同的Activity调用getResources复返服从却是一样的。
Context自己是一个纯的abstract类,ContextWrapper是对Context的一个包装良友,它的里面包含了一个Context对象,其实对ContextWrapper的活动调用最终皆是调用其中的Context对象完成的,至于ContextThremeWrapper,很赫然和Theme关联,是以Activity从ContextThemmWrapper剿袭,而Service从ContextWrapper剿袭,ContextImpl是惟逐个个真的结束了Context中活动的类。 从上头的剿袭干系来看,每一个Activity即是一个Context,每一个Service即是一个Context,这也即是为什么使用Context的处所不错被Activity或者Service替换了。
创建Context 字据前边所说,由于结束了Context的唯有ContextImpl类,Activity和Service本莫得真的的结束,他们只是里面包含了一个真的的Context对象良友,也即是在在创建Activity或者Service的时分细目要创建爱你一个ContextImpl对象,并赋值到Activity中的Context类型变量中。那咱们就来望望Andorid源码中有哪些处所创建了ContextImpl. 据统计Android中创建ContextImpl的处所一共有7处:
在PackageInfo.makeApplication()中 在performLaunchActivity()中 在handleCreateBackupAgent()中 在handleCreateService()中 2次在hanldBinderAppplication()中 在attach()活动中由于创建ContextImpl的基甘心趣雷同,是以这里只会分析几个相比有代表性的处所: 1、 Application对应的Context 在诳骗体式启动时,皆会创建一个Application对象,是以转折调用到handleBindApplication()活动。
其中data.info是LoadedApk类型的,到getPackageInfoNoCheck中望望源码
里面其实调用的是getPackageInfo,不时跟进:
由于includeCode传入的是true,是以最初从mPackages中取得,如果莫得,则new一个出来,并放入mPackages里面去,矜重,这里的mPackages是ActivityThread中的属性。 底下不时分析一下LoadedApk这个类中的makeApplication函数
这里创建了一个ContextImpl对象,并调用了它的init活动,当今过问init活动。
对mPackageInof和mResources两个变量运更始 回到makeApplication中,创建了一个Application对象,并将appContext传进去,其实即是将appContext传递给ContextWrapper中的Context类型变量(Application亦然剿袭ContextWrapper) 2、Activity中的Context 在创建一个Activity时,经过转折调用,会试验handleLaunchActivity(),然后调用performLaunchActivity(),该活动创建ContextImpl代码如下:
由于getPackageInfo函数之前也曾分析过了,略略有点区别,然而大要过程是差未几的,是以此处的appContext试验init之后,其中的mPackages变量和mResources变量时一样的,activity通过attach函数将该appContext赋值到ContextWrapper中的Context类型变量。
3、Service中的Context 雷同 在创建一个Service时,经过转折调用会调用到scheduleCreateService活动,之后会巧用handleCreateService
其念念路和上头两个基本一样,在此就不再胪陈。
Context对资源的造访 很明确,不同的Context得到的皆是统一份资源。这是很好意会的,请看底下的分析
app得到资源的情势为context.getResources,而真的的结束位于ContextImpl中的getResources活动,软件开发在ContextImpl中有一个成员 private Resources mResources,它即是getResources活动复返的服从,mResources的赋值代码为:
底下看一下ResourcesManager的getTopLevelResources活动,这个活动的念念想是这样的:在ResourcesManager中,统统的资源对象皆被存储在ArrayMap中,最初字据现时的央求参数去查找资源,如果找到了就复返,不然就创建一个资源对象放到ArrayMap中。有少量需要说明的是为什么会有多个资源对象,原因很简便,因为res下可能存在多个适配不同修复、不同划分率、不同系统版块的目次,按照android系统的诡计,不同修复在造访统一个诳骗的时分造访的资源不错不同,比如drawable-hdpi和drawable-xhdpi即是典型的例子。
字据上述代码中资源的央求机制,再加上ResourcesManager接收单例模式,这样就保证了不同的ContextImpl造访的是统一套资源,矜重,这里说的统一套资源巧合是统一个资源,因为资源可能位于不同的目次,但它一定是咱们的诳骗的资源,约略这样来刻画更准确,在修复参数和袒露参数不变的情况下,不同的ContextImpl造访到的是统一份资源。修复参数不变是指手机的屏幕和android版块不变,袒露参数不变是指手机的划分率和横竖屏景象。也即是说,尽管Application、Activity、Service皆有我方的ContextImpl,况兼每个ContextImpl皆有我方的mResources成员,然而由于它们的mResources成员皆来自于惟一的ResourcesManager实例,是以它们看似不同的mResources其实皆指向的是统一块内存(C说念话的办法),因此,它们的mResources皆是统一个对象(在修复参数和袒露参数不变的情况下)。在横竖屏切换的情况下且诳骗中为横竖屏景象提供了不同的资源,处在横屏景象下的ContextImpl和处在竖屏景象下的ContextImpl造访的资源不是统一个资源对象。
现年27岁的若纳坦-塔与勒沃库森的合同2025年到期,若纳坦-塔在德转的最新身价为3000万欧元。
代码:单例模式的ResourcesManager类
getApplication和getApplicationContext的区别
getApplication复返服从为Application,且不同的Activity和Service复返的Application均为统一个全局对象,在ActivityThread里面有一个列表专诚用于爱戴统统诳骗的application
getApplicationContext复返的亦然Application对象,只不外复返类型为Context,望望它的结束
上头代码中mPackageInfo是包含现时诳骗的包信息、比如包名、诳骗的装配目次等,原则上来说,看成第三方诳骗,包信息mPackageInfo不能能为空,在这种情况下,getApplicationContext复返的对象和getApplication是统一个。然而对于系统诳骗,包信息有可能为空,具体就不深刻考虑了。从这种角度来说,对于第三方诳骗,一个诳骗只存在一个Application对象,且通过getApplication和getApplicationContext得到的是统一个对象,两者的区别只是是复返类型不同。
在此记挂一下: (1)Context是一个综合类,ContextWrapper是对Context的封装,它包含一个Context类型的变量,ContextWrapper的功能函数里面其实皆是调用里面的Context类型变量完成的。Application,Service,Activity等皆是径直或者迂回剿袭自ContextWrapper,然而并莫得真的的结束其中的功能,Application,Service,Activity中对于Context的功能皆是通过其里面的Context类型变量完成的,而这个变量的真的对象必定是ContextImpl,是以没创建一个Application,Activity,Servcice便会创建一个ContextImpl,况兼这些ContextImpl中的mPackages和mResources变量皆是一样的,是以岂论使用Acitivty照旧Service调用getResources得到考虑的服从 (2)在一个apk中软件开发公司,Context的数目等于Activity个数+Service个数+1.