浅析Android Context

一:什么是Context?

Context,sdk中的解释如下:interface to global information about an application environment.This is an abstract class whose implementation is provided by the Android System.It allows access to application-specific resources and classes,as
well as up-calls for application-level operations such as launching activities,broadcasting and receiving intents,etc.

简单的总结为三条:

1.它描述的是一个应用程序的环境的信息,可以被称作为上下文。

2.该类是一个抽象类,Android提供了该抽象类的具体实现类。

3.通过它我们可以获取应用程序的资源和类,也包括采取一些应用级别的操作,例如,启动一个Activity,发送广播,接收Intent.

二:Context抽象类的继承关系

由上图我们可以看出,Activity,service,Application实则全为Context的子类。

三:Context实例的创建时机以及数目

通常来说,程序创建Context实例的时机为以下三种情况:

1.创建Application对象时,而且整个App共有一个Application对象。

2.创建Service对象时

3.创建Activity对象时

由上可知,一个应用程序中Context实例个数的计算公式为:

总Context数 = Service个数 + Activity个数 + 1(Application对应的Context实例)

四:Context的获取方式以及全局获取Context的技巧

因为Activity,Service本身就是一个context对象,所以在其中获取Context非常简单,但当脱离了这些与Context类有紧密关系的类时,我们该如何获得呢?当然这也有许多方法可以获得,但我在此给大家分享一种方法,定制一个自己的Application类,以便于管理程序内一些全局的状态信息,如Context。创建一个MyApplication继承自Application,代码如下:(以下代码来自《第一行代码》)

<span style="font-size:14px;">public class MyApplication{

	private static Context context;

	@override
	public void onCreate(){
		context = getApplicationContext();
	}

	public static Context getContext(){
		return context;
	}
}</span>

接下来我们需要告知系统,当程序启动的时候应该初始化MyApplication而不是默认的Application类,操作也很简单,修改AndroidManifest.xml文件的<application>标签下的内容:

<application
    android:name="com.example.hhw.MyApplication"
    ....>
</appliaction>

之后,你可以通过以下方式在你想用Context的任何地方得到它。

<span style="font-size:14px;">MyApplication.getContext();</span>

五:Activity,Application的Context以及内存泄露

首先,Activity的Context和Application的Context肯定不是一个东西,一个是当前活动的Context,它的生命周期仅限于此活动,一个是整个应用程序的Context,它的生命周期伴随着整个程序,鉴于Activity的Context的特点,滥用它往往会造成内存泄露,如下代码所示:

<span style="font-size:14px;">public class TestContext{
	private static TestContext testContext;
	private Context context;

	private TestContext(Context context){
		this.context = context;
	}

    public static synchronized TestContext getInstance(Context context){
    	if(null == testContext)
    		testContext = new TestContext(context);
    	return testContext;
    }
}</span>

显而易见,上述单例模式中textContext是强引用static类型,往往它的生命周期伴随着整个应用程序,但你传递进来的Context若是一个Activity的,只要我们这个应用程序还活着,它就没有办法正常的回收,这就造成了内存的泄露。解决的方法很简单,将初始化TestContext是传递的参数变为context.getApplicationContext()既可,因为用此方法获得的是应用程序的context,因此就不用担心内存泄露了。

public class TestContext{
	private static TestContext testContext;
	private Context context;

	private TestContext(Context context){
		this.context = context;
	}

    public static synchronized TestContext getInstance(Context context){
    	if(null == testContext)
    		testContext = new TestContext(context.getApplicationContext());
    	return testContext;
    }
}

既然如此的话,在能使用context的地方全部替换成context.getApplicationContext()不就皆大欢喜了吗?很遗憾的来说,这样不行,因为他们根本不是一个东西,它们的应用场景是不同的,并非所有的Activity的Context的场景,Application的Context依然可以,一下是我总结出来的一个表格,表示了它俩之间的应用场景:

  Application Activity
show a dialog NO YES
Layout Inflation NO YES
start an activity NO YES
Bild to a Service YES YES
Send a Broadcast YES YES
Register BrocastReceiver YES YES
start a service YES YES
load resource values YES YES

其实我们只要把握住两条原则即可:

1.凡是和UI相关的,都不建议使用Application的Context.

2..不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的,若不一样,请考虑一下是否可以使用Application的Context.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 05:08:57

浅析Android Context的相关文章

从源码中浅析Android中如何利用attrs和styles定义控件

一直有个问题就是,Android中是如何通过布局文件,就能实现控件效果的不同呢?比如在布局文件中,我设置了一个TextView,给它设置了textColor,它就能够改变这个TextView的文本的颜色.这是如何做到的呢?我们分3个部分来看这个问题1.attrs.xml  2.styles.xml  3.看组件的源码. 1.attrs.xml: 我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性 你可以找到attr

浅析Android Handle机制

一.Handle的用例: 1.创建handle实例 new handle(); 2.发送信息载体(Message) sendMessage(msg); 3.处理消息 handleMessage(Message msg){}; 二.原理浅析 结合以上的handle调用三部曲,我们将顺藤摸瓜理清Handle.Looper.Message.MessageQueue的逻辑与关系. 1.new Handle():这个操作将生成一个Handle实例,handle实例有三个属性mLooper.mQueue.m

Android Context 是什么?

andorid 开发(42)  版权声明:本文为博主原创文章,未经博主允许不得转载. [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] PS:修该了一些有误区的地方. 引言 Context对于Android开发人员来说并不陌生,项目中我们会经常使用Context来获取APP资源,创建UI,获取系统Service服务,启动Activity,绑定Service,发送广播,获取APP信息等等.那么Context到底是什么?Context又是怎

浅析android OCR文字识别

这学期有门课程老师要求用JAVA实现一个OCR文字识别的程序,所以就花了一些时间研究了一下在安卓端如何实现 OCR的引擎是用的开源项目tesseract-ocr 这个安卓版的地址:https://code.google.com/p/tesseract-android-tools/ 但是自己在编译的时候老是出错,于是在网上寻找到了别人编译好安卓可用的tess-two导入到项目中(参考文章地址 http://www.cnblogs.com/hangxin1940/archive/2012/01/13

浅析android下如何通过jni监控wifi网络连接、dhcpcd执行和power电源控制

浅析android下如何通过jni监控wifi网络连接.dhcpcd执行和power电源控制 =============================================================================================================libs/android_runtime/android_net_wifi_Wifi.cpp部分jni接口static JNINativeMethod gWifiMethods[] = {

关于Android Context一些总结

1.首先什么是context? 文档语焉不详,说是resource什么的,反正是没看懂,实际上可以认为它是一个指向parent对象的指针,受到那个parent对象的控制. 2.为什么需要context? 试想一下这个语句: Button myButton =newButton(this); 这个this就是context,前面说了它指向了parent对象,那指向了哪里?为什么需要这么做?原因是Button为了能完成自己的使命(响应各种操作)就得让Android系统知道自己是属于哪个Activit

浅析android适配器adapter中的那些坑

做项目中遇到的,折磨了我将近两天,今天把经验分享出来.让大家以后少走点弯路,好了.简单来说一下什么是android的适配器,怎样定义.怎样添加适配器的重用性.怎样去减少程序的耦合性 适配器顾名思义是用来做适配的,可是他是怎样做适配的.机制是什么.作用是什么,好,相信写java的都是知道什么是面向对象编程吧,这里用面向对象来解释非常好理解.事实上适配器是把每一个对象放在其空间上然后在andorid页面显示,如今再来理解,对象事实上就是数据的抽象体吧,而页面显示通常是xml也就是视图吧,那么数据以视

浅析Android 开源框架ImageLoader的用法

一.前言 在Android开发中,会经常涉及到显示图片的相关操作,在网上查阅资料,ImageLoader得到大家广泛的使用,本篇文章针对初使用者的一个向导,同时也是自己使用该框架的一个总结,主要包含: ## 源码浅析 ## ## 使用教程 ## ## 用法总结及demo下载 ## 二.源码浅析 从用法来看,我们在使用该框架的时候,会先做一个初始化操作(一般在Application中), ImageLoader imageLoader = ImageLoader.getInstance(); im

android Context

Context是维持Android程序中各组件正常工作的核心类 context的继承结构 ContextWrapper :上下文功能包装类 ContextImpl :上下文功能的实现类  (Context Implement) ContextThemeWrapper:上下文主题包装类 一个应用程序Context的数量为  =  Activity数量+Service数量+ 1(Application本身)