Android中Context的理解

Content:中文直译上下文

  • 1、它描述的是一个应用程序环境的信息,即上下文。

  • 2、该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类。

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

应用程序创建Context实例的情况有如下几种情况:

  • 1、创建Application对象时,而且整个App共一个Application对象。
    每个应用程序在第一次启动时,都会首先创建Application对象。创建Application的时机在创建handleBindApplication()方法中

  • 2、创建Service对象时。
    通过startService或者bindService时,如果系统检测到需要新创建一个Service实例,就会回调handleCreateService()方法,

  • 3、创建Activity对象时。
    通过startActivity()或startActivityForResult()请求启动一个Activity时,如果系统检测需要新建一个Activity对象时,就会回调handleLaunchActivity()方法,该方法继而调用performLaunchActivity()方法,去创建一个Activity实例,并且回调onCreate()、onStart()方法等。

Application中的Content与Activity中的Content的区别

Markdown及扩展

Android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中常用两种context,一种是application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。>

区别和联系

 public class MyActivity extends Activity {     public void method() {     mContext = this; // since Activity extends Context     mContext = getApplicationContext();          }}

1、this是Activity的实例,扩展了Context,其生命周期是Activity 创建到销毁。
2、getApplicationContext()返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁。
3、Activity.this的context 返回当前activity的上下文,属于activity ,activity摧毁他就摧毁

搞清楚了生命周期就会在使用过程中犯错误,比如有一个全局的数据操作类用到了context,这个时候就要getApplicationContext 而不是用ACtivity,这就保证了数据库的操作与activity无关(不会一直引用Activity的资源,防止内存泄漏)

应用场景

 protected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this);        label.setText("Leaks are bad"); setContentView(label); }

1、把activity context传递给view,意味着view拥有一个指向activity的引用,进而引用activity占有的资源:view hierachy, resource等。

2、如果context发生内存泄露的话,就会泄露很多内存。这里泄露的意思是gc没有办法回收activity的内存。

3、 Leaking an entire activity是很容易的一件事。当屏幕旋转的时候,系统会销毁当前的activity,保存状态信息,再创建一个新的activity。

比如我们写了一个应用程序,它需要加载一个很大的图片,我们不希望每次旋转屏幕的时候都销毁这个图片重新加载。
实现这个要求的简单想法就是定义一个静态的Drawable,这样Activity类创建销毁它始终保存在内存中。

public class myactivity extends Activity {     private static Drawable sBackground;     protected void onCreate(Bundle state) {     super.onCreate(state);     TextView label = new TextView(this);     label.setText("Leaks are bad");     if (sBackground == null) {     sBackground = getDrawable(R.drawable     .large_bitmap);     }     label.setBackgroundDrawable(sBackground);     } }

这段程序看起来很简单,但是却问题很大。

1、当屏幕旋转的时候会有leak(即gc没法销毁activity)。我们刚才说过,屏幕旋转的时候系统会销毁当前的activity。

2、但是当drawable和view关联后,drawable保存了view的reference,即sBackground保存了label的引用,而label保存了activity的引用。

3、既然drawable不能销毁,它所引用和间接引用的都不能销毁,这样系统就没有办法销毁当前的activity,于是造成了内存泄露。

gc对这种类型的内存泄露是无能为力的。避免这种内存泄露的方法是避免activity中的任何对象的生命周期长过activity,避免由于对象对activity的引用导致activity不能正常被销毁。我们可以使用application context。

Application

application context伴随application的一生,与activity的生命周期无关
application context可以通过Context.getApplicationContext()或者Activity.getApplicationContext()方法获取。

//1、定制一个自己的Application:首先创建一个MyApplication类继承自Applicationpublic class MyApplication extends Application{    private static Context context;    public void onCreate(){      context=getApplicationContext();    }    public static Context getContext(){    return context;    }}//2、注意:当程序启动的时候应该初始化MyApplication类,而不是默认的Application类。在AndroidMainifest.xml文件的标签下进行指定就可以了。android:name="com.example.hl.MyApplication"

这样就已经实现了一种全局获取Context的机制,之后想在项目中使用Application的Context时,只需调用一下MyApplication.getContext()就可以了。

避免context相关的内存泄露,记住以下几点:

* 1. 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的

* 2. 对于生命周期长的对象,可以使用application context

* 3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化

更多相关文章

  1. 类和 Json对象
  2. Android(安卓)Resource介绍和使用
  3. Android中文API(144) —— JsonWriter
  4. Action for BroadcastReceiver's method
  5. Android之Handler用法总结
  6. android通过ksoap2对webservice的解析
  7. SlidingMenu和ActionBarSherlock结合做出出色的App布局,Facebook
  8. Android(安卓)View的介绍和使用
  9. Android(安卓)如何开发 Bottom Navigation 风格

随机推荐

  1. AndroidResource
  2. Android相机Camera基础知识
  3. [android]Android异步处理系列文章索引
  4. Android(安卓)图表开源框架之MPAndroidCh
  5. GridView控件的简单使用
  6. Android学习笔记(二八):字体
  7. Android(安卓)SDK Manager 更新
  8. Android(安卓)xml资源文件中@、@android:
  9. android:ellipsize的使用
  10. 打包Android应用程序