关于Context的理解(转)

关于Context的理解

Context可以做很多事情,打开activity、发送广播、打开本包下文件夹和数据库、获取classLoader、获取资源等等。

通常情况下获取当前应用的context的方法是getApplicationContext,
但是通过根据其他的packageName如何构造 Context呢?

CreatePackageContext这个方法有两个参数:
1.packageName 包名,要得到Context的包名
2.flags 标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。 CONTEXT_INCLUDE_CODE的意思是包括代码,也就是说可以执行这个包里面的代码。
CONTEXT_IGNORE_SECURITY的意思是忽略安全警告,如果不加这个标志的话,有些功能是用不了的,会出现安全警告。

CreatePackageContext方法在找不到包名的时候会报NameNotFoundException异常,所以我们要捕获它。

try
{
Context ctx= createPackageContext("com.android123.Cwj", 0);

//ctx已经是com.android123.cwj的实例
}
catch (NameNotFoundException e)
{
//可能由于 pacakgeName不存在所以必须处理该异常
}
复制代码需要注意的是,createPackageContext方法的第二个参数可选为CONTEXT_INCLUDE_CODE 和 CONTEXT_IGNORE_SECURITY ,
定义分别为4和2,上面为0。一般忽略安全错误问题可以通过CONTEXT_IGNORE_SECURITY 标记,
同时可能还需要处理 SecurityException 异常.

package chroya.demo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

class Main extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

public void print(String msg) {
Log.d("Main", "msg:"+ msg);
}
}
本包的调用Main的print方法的代码块如下:
Context c = createPackageContext("chroya.demo", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
//载入这个类
Class clazz = c.getClassLoader().loadClass("chroya.demo.Main");
//新建一个实例
Object owner = clazz.newInstance();
//获取print方法,传入参数并执行
Object obj = clazz.getMethod("print", String.class).invoke(owner, "Hello");
---------------------------------------------------
官方文档的解释是:Context提供了关于应用环境全局信息的接口。它是一个抽象类,它的执行被Android系统所提供。它允许获取以应用为特征的资源和类型。同时启动应用级的操作,如启动Activity,broadcasting和接收intents。
常用的Context的子类是Activity和Service,我们可以将context理解为类似于Window下的句柄,但Window下的句柄,每个资源都可以是一个句柄,比如一个控件、图片等等,但在android中context只能是Activity和Service等这一类。如果要在 Activity中新建一个dialog,在这个dialog中要添加一个控件,要给这个控件传递一个context参数,只能是Activity的实例,不能是这dialog,因为控件的事件需要activity来处理。所以context是一个统领一些资源(应用程序环境变量等)的上下文(理解为句柄)。

我们在一个activity中有如下代码:

Toast.makeText(null, "", Toast.LENGTH_LONG).show();

那么程序运行时会有空指针一场,就是因为第一个参数Context类型,我们传了null,这样运行到这段代码时,系统不知道activity的环境变量,所以就会出错。
---------------------------------------
context其实就是句柄,只不过不像windows一样,每个资源都可以是一个句柄,Android的一个句柄包含了很多全局信息,比如说Activity就是一个句柄

在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context,通常我们在各种类和方法间传递的是activity context
---------------------------------------
Context是一个抽象对象,它的子类比较多,Activity就是它的子类,Service也是。
---------------------------------------
public class DrawInfoPointOnView extends View {
public DrawInfoPointOnView(Context context){
super(context);
}
private MapDBAdapter mDbHelper;
private Cursor mLocationCursor;

@Override
protected void onDraw(Canvas canvas) {
mDbHelper = new MapDBAdapter(this); 该语句出错
mDbHelper.open();

请问各位是不是View不能作为Context ?那类能作为Context?

context是上下文对象,你在掉用这个类的Activity里定义一个context 然后在oncreate方法里给context赋值,context = this;把context传到这个类里来,然后在你出错的地方把你那个this换成context就没问题啦。你那里出错的原因是用的“this”不对,应该是Activity的context;
---------------------------------------
很多初入Android开发的网友向我们问到Context有什么作用,很多地方都用到它,这里Android123给这些新入门的网友做个简单的解释:

Context字面意思上下文,位于framework package的android.content.Context中,其实该类为LONG型,类似Win32中的Handle句柄,很多方法需要通过 Context才能识别调用者的实例,比如说Toast的第一个参数就是Context,一般在Activity中我们直接用this代替,代表调用者的实例为Activity,而到了一个button的onClick(View view)等方法时,我们用this时就会报错,所以我们可能使用ActivityName.this来解决,主要原因是因为实现Context的类主要有Android特有的几个模型,Activity、Service以及BroadcastReceiver。

常规需要Context实例的方法主要有各种Service实现的类,比如说SensorManager在实例化时需要 getSystemService(String)方法就必须由Context的实例执行,还有一些私有的文件系统I/O比如说 openFileInput以及常用的Toast的makeText方法。

你可能感兴趣的:(关于Context的理解(转))