您的位置:首页 > 移动开发

关于context和getapplicationcontext

2015-07-25 17:24 302 查看
刚看了一篇关于二者关系的文章,最后一段没什么用,所以就截取了一段,自己做一下分析,哈哈哈。以下是原文

Context,我们在android开发中经常见到这个名词,尤其是某些方法的参数列表,像是我们Toast中的makeText()中的第一个参数,就是Context。可以这么说,Context是 android中的基础,只有切实掌握好Context的概念和用法,我们才能写出更好的代码。那么,现在就让我们一起来看一下所谓的Context。

Context,如果是直接从文档翻译过来,就真的是十足的专业了:提供应用环境全局信息的接口,并且这个接口是由抽象类实现的,它的执行被android系统所提供,允许我们获取以应用为特征的资源和类型,同时启动应用级的操作,如启动Activity,broadcasting和接收intent。

从这段话就可以发现,Context就是一个作为接口使用的抽象类,而且这个接口提供的是应用的全局信息,因为是android系统所提供的,所以我们大多时候都是可以直接得到的,这点会在下面讲到。我们来看看它的用处,允许我们获取以应用为特征的资源和类型,同时启动应用级的操作。什么意思?通俗来讲,就是我们可以获取其他应用的资源和类,至于下半句的启动应用级的操作,我们可以暂时忽略,因为不是这里的重点。

一.Context的作用

Context的最大作用就是我们可以通过传递它来获得其他Activity或Application的相关资源和方法,它就相当于它们的引用,我们通过引用来获得对象的封装,这也是我们面向对象的基础,所以,我们主要利用它来加载和访问资源。

二 .Context的类型
Context的类型有两种,一种是Activity-Context,另一种是Application-Activity,这两种的区别就在于它们的生命周期不一样,一个是随着Activity的销毁而销毁,另一个是伴随整个Application,鉴于我们以前学习java,C++这些语言的经验,都会意识到,这些生命周期的不同可能会导致不同行为以及一些错误,这些都会在接下来讲到,因为它们是我们使用Context必须注意的。
1.Application-Context
这个之所以先讲,是因为这个比较麻烦,在于它的获取需要通过一些手段。
Application-Context的生命周期是整个应用,所以,对于它的使用必须慎重,大部分情况下都要避免使用它,因为它会导致内存泄露的问题。我们先来举个例子,如果我们现在在一个Activity中引入一个Application-Context,那么,当我们这个Activity关闭的时候,这个Application-Context是不会消失的,因为它的生命周期要比我们的Activity长,如果只是一些用来计算的数据还好,但是如果这个Context与我们的Activity的创建有关,或者与我们在Activity要销毁的资源比如图片资源有关,那么,问题就大条了!因为我们的Activity或图片就不能正常销毁,因为它与Application-Context相关联,如果不能正常的释放掉与它们相关的内存,就会出现所谓的内存泄露的问题。这种问题有时候是非常隐晦的,以至于我们根本无法察觉到,所以我们必须遵守相关的使用原则。
现在我们以一个例子来示例如何获得Application-Context。
要想获得Application-Context,我们可以先声明一个Application的子类。

class A extends Application{}


现在,我们在这个类中添加一些东西来证明可以通过Context来获得A的相关资源和方法。这次我们使用一个Toast。
首先,是在我们的类A里添加以下的内容:

String s = "hello";
public String getString(String str){
s = str;
return s;
}


然后再在我们的Activity B中尝试取用A的数据和方法:

A a = (A)getApplicationContext();
String s = a.s;
s = a.getString("hello word");
Toast.makeText(this, s, Toast.LENGTH_LONG).show();


然后我们还必须注意在我们的mainfest文件中注册我们的application:

<application android:name=".A"></application>


注意,我们的mainfes始的at文件中一开pplication是没有名字的,因为我们一般都只是启动一个Activity,而不是一个application,所以,可以将我们这个application的名字注册为继承自Application的子类A,这样才能正常显示出一个Toast出来。如果没有这么做,就可能报出这样的错误:android.app.Application cannot
be cast to A。
在上面的例子中可以看到,通过一个Application的子类就能在我们的Activity中调用它的资源和方法,但是其实完全可以不用这样做,声明一个class,然后new一个实例同样可以做到这点,但是这里只是想要大家明白,Context的确可以传递相关类的引用,并且通过这个引用来获取相关类的资源和方法,而且这个Context甚至可以转化为具体的子类,我们的getApplicationContext()返回的其实是一个Context,之所以能将它转换为A,是因为Context传递的就是Application-Context,它是一个Application类型的,而类A是Application的子类,父类转化为子类,这里就会有个疑问,就是我们的父类是不可以强制转化为子类的,因为子类可能有父类没有的方法,这样的转化就会出现问题,但是,我们也知道,可以将子类的引用转化为父类,因为父类的引用是可以指向子类的,所以这里是想说明我们的Context真的是一个引用。
Application-Context的生命周期为整个Application,所以如果是一些需要在整个应用期间都存在的资源,我们可以将它放进一个Application-Context中,然后通过获取这个Context来使用它们。
2.Activity-Context
正如上面讲的一样,这个Context的生命周期是和得到它的引用的Activity一样长,如果这个Activity结束了,那么,这个Context也会得到释放。它并不像我们上面的Application-Context需要特意去获得,可以在一个Activity中使用this就可以获得当前Activity的Context。还是拿上面例子中的Toast.makeText(this, s, Toast.LENGTH_LONG).show(),其中的this就是当前的Activity-Context,但是,一味的使用this是很危险的,我们要注意的就是,在匿名内部类如果单纯只是使用this是会出错的,因为内部类中使用this得到的是内部类的对象引用,而不是我们要得到的外部类的引用,于是,这时候就必须使用类名.this这种方式,这种做法在按钮的事件监听中是特别要注意的。
3.使用规则
因为使用Application-Cntext会出现内存泄露的危险,所以我们一般都是使用Activity-Context。下面就是这两者的使用规则:
(1)不要让生命周期长的对象引用Activity-Context,保证引用要与Ativity本身生命周期是一样的,对于生命周期长的对象,使用Application-Context 。
如果你想要在某个Activity的界面上显示某个组件,比如说Toast,那么,请把你的Activity的Context作为参数传给Toast,这样就能将你的Activity和Toast关联起来,但是,如果你想要在一个Activity中设置好你的Toast,然后再在另一个Activity中显示,记住,你可以有两种选择,一种,就是通过我们的Intent:

Intent intent = new Intent(Activity1.this, Activity2.class);
startActivity(intent);


这个Activity1就是我们要显示Toast的Activity,而Acticity2就是我们设置Toast的Activity。
原文http://www.cnblogs.com/wenjiang/archive/2012/10/15/2724923.html

以上。
整体来说,就是activity的context也就是当前activity.this,它的生命周期是和activity一样的。同理,application的context就会一直伴随着整个程序。让一个dialogshow一下的话,或者popwindowshow一下,就要用activity的context了。像那些和图片有关的持有对象的context必然要用activity的context,否则你一直持有对图像资源的引用,那当然就会造成内存泄露,是吧。还有什么basectx那些,没去看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: