随手可得的Application对象
2015-07-16 23:50
429 查看
在Android的开发当中,Application和Context对象应该是我们接触最多的对象了,特别是Context对象。
当我们在某个Activity或者Service当中时,由于它们本身就是Context的子类,因此“this”可以等价于Context对象使用。然而,在很多时候这个Context并不是那么随手可得,试想一下以下情况:
需要用到Context的SDK,开发者为了使用SDK需要添加Context的传递代码;
二次打包的加插代码如果需要使用Context,则需要修改原来的逻辑,把Context传递进来;
注入到Java环境之后,需要用到Context,访问各种IPC的服务;
等等
因此如果可以找到一种方式,可以在不接触原来逻辑的前提下,获取到当前进程的Application对象,那上述提及的问题就可以迎刃而解了。这里说得有点抽象,比如当我们编写自定义的Application类时,一般会这添加一个静态方法getContext(或者其他类似名字),如下所示:
这个代码大家一看就懂,主要就是方便后面要使用Context时使用的,由于Application是全局的,因此可以防止内在泄漏。但如何可以做过不通过这种方式,甚至在没有自定义Application的情况下,也可以拿到这个Application对象呢?
其实这次的干货不多,这里我提供一个方法,这个方法可以兼容1.6至5.1(之后的固件应该也能兼容)。
主要是通过反射的方式,获取系统类的静态字段,过程如下:
通过RuntimeInit类,获取到mApplicationObject静态字段,这个字段的类型为android.app.ActivityThread$ApplicationThread;
通过ApplicationThread类,获取this$0字段,注意这个是编译器生成的,这个字段的类型是android.app.ActivityThread;
通过ActivityThread类,获取其mInitialApplication字段,这个字段即是Application对象;
由于涉及到反射调用,完整代码就不写好,写个简单的伪代码吧
可以肯定,这不是唯一的方法,大家有什么好的方式,欢迎分享。
当我们在某个Activity或者Service当中时,由于它们本身就是Context的子类,因此“this”可以等价于Context对象使用。然而,在很多时候这个Context并不是那么随手可得,试想一下以下情况:
需要用到Context的SDK,开发者为了使用SDK需要添加Context的传递代码;
二次打包的加插代码如果需要使用Context,则需要修改原来的逻辑,把Context传递进来;
注入到Java环境之后,需要用到Context,访问各种IPC的服务;
等等
因此如果可以找到一种方式,可以在不接触原来逻辑的前提下,获取到当前进程的Application对象,那上述提及的问题就可以迎刃而解了。这里说得有点抽象,比如当我们编写自定义的Application类时,一般会这添加一个静态方法getContext(或者其他类似名字),如下所示:
class final MyApplication extends Application{ private static Application sInstance; @Override public void onCreate(){ sInstance = this; } public static Application getContext(){ return sInstance; } //... //... }
这个代码大家一看就懂,主要就是方便后面要使用Context时使用的,由于Application是全局的,因此可以防止内在泄漏。但如何可以做过不通过这种方式,甚至在没有自定义Application的情况下,也可以拿到这个Application对象呢?
其实这次的干货不多,这里我提供一个方法,这个方法可以兼容1.6至5.1(之后的固件应该也能兼容)。
主要是通过反射的方式,获取系统类的静态字段,过程如下:
通过RuntimeInit类,获取到mApplicationObject静态字段,这个字段的类型为android.app.ActivityThread$ApplicationThread;
通过ApplicationThread类,获取this$0字段,注意这个是编译器生成的,这个字段的类型是android.app.ActivityThread;
通过ActivityThread类,获取其mInitialApplication字段,这个字段即是Application对象;
由于涉及到反射调用,完整代码就不写好,写个简单的伪代码吧
Applicatioin app = RuntimeInit.mApplicationObject.this$0.mInitialApplication;
可以肯定,这不是唯一的方法,大家有什么好的方式,欢迎分享。
相关文章推荐
- Android依赖注入:Dagger(Part 3)
- android--轻量级缓存框架ASimpleCache分析
- 基于cocos2dx的飞机大战学习[四]-添加英雄子弹
- 【Android4高级编程笔记】深入探讨Android Activity
- 集成支付宝接口 swift
- android--系统体系结构
- 在Window环境下,使用CodeBlocks+GNUStep 配置Objective-C开发环境
- ios学习笔记-06-实践
- android--SurfaceView和View最本质的区别
- 工作总结-C#抽象类,接口,以及UnityAction
- android 与 蓝牙模块 hc06通信app 开发要点
- Android Day03-SQLite数据库操作及ListView详解
- Cisco IOS XR在VMware环境下如何增加物理接口
- Objective-C学习笔记之SEL和@selector
- 在Inspector 中 设置添加回调函数 - Unity3d编辑器扩展
- 我的Android进阶之旅------> Android为TextView组件中显示的文本添加背景色
- android 自定义view
- iOS多线程
- 修改android应用包名
- 修改android应用包名