看到很多Android程序里面传Context对象,但不知道这个对象怎么理解,对应AP的实例还是什么其它?
跟this指针有什么联系与区别?

解决方案 »

  1.   


     Context   mcontext;
        mcontext=this.getApplicationContext();
        
        mcontext.getApplicationContext();
    上面的语法都没有错,但不知道那是那了.this指针代表的是Activity实例?那Context指的是什么大小的上下文?AP的上下文?
    如果是AP的上下文那肯定是Context包含this指针了,那怎么用this指针又可以访问到Context?
    难道他们指针嵌套了?还是互指对方?
      

  2.   

    Android基础概念Context的作用
    http://www.devdiv.com/thread-27359-1-1.html很多初入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方法。
      

  3.   

    Context指什么,那些可以做Context?http://www.eoeandroid.com/thread-19959-1-1.html
      

  4.   

    android context理解http://liaowb1234.blog.163.com/blog/static/7715554720106911396569/在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。
    比如一个activity的onCreate:
    protected void onCreate(Bundle state) {
            super.onCreate(state);        TextView label = new TextView(this); //传递context给view control
            label.setText("Leaks are bad");        setContentView(label);
    }
    把activity context传递给view,意味着view拥有一个指向activity的引用,进而引用activity占有的资源:view hierachy, resource等。
    这样如果context发生内存泄露的话,就会泄露很多内存。
    这里泄露的意思是gc没有办法回收activity的内存。Leaking an entire 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);//drawable attached to a view        setContentView(label);
            }
    }
    这段程序看起来很简单,但是却问题很大。当屏幕旋转的时候会有leak(即gc没法销毁activity)。
    我们刚才说过,屏幕旋转的时候系统会销毁当前的activity。但是当drawable和view关联后,drawable保存了view的 reference,即sBackground保存了label的引用,而label保存了activity的引用。既然drawable不能销毁,它所 引用和间接引用的都不能销毁,这样系统就没有办法销毁当前的activity,于是造成了内存泄露。gc对这种类型的内存泄露是无能为力的。避免这种内存泄露的方法是避免activity中的任何对象的生命周期长过activity,避免由于对象对 activity的引用导致activity不能正常被销毁。我们可以使用application context。application context伴随application的一生,与activity的生命周期无关。application context可以通过Context.getApplicationContext或者Activity.getApplication方法获取。避免context相关的内存泄露,记住以下几点:
    1. 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的
    2. 对于生命周期长的对象,可以使用application context
    3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化
      

  5.   

    根据packageName构造Context 通常情况下获取当前应用的context的方法是getApplicationContext,
    但是通过根据其他的packageName如何构造 Context呢? 
    Android平台的应用实例其实还可以通过其他方式构造。
    比如代码   
         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 异常.
      

  6.   

    Android中Context简介
    http://blog.csdn.net/zhangqijie001/archive/2010/09/17/5891682.aspx
    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。 Context提供了关于应用环境全局信息的接口。它是一个抽象类,它的执行被Android系统所提供。它允许获取以应用为特征的资源和类型。同时启动应用级的操作,如启动Activity,broadcasting和接收intents。 下面介绍Context的一些get方法,通过这些get方法可以获取应用环境全局信息: 1.public abstract Context getApplicationContext () 
    Return the context of the single, global Application object of the current process. 2.public abstract ApplicationInfo getApplicationInfo () 
    Return the full application info for this context's package. 3.public abstract ContentResolver getContentResolver () 
    Return a ContentResolver instance for your application's package. 4.public abstract PackageManager getPackageManager () 
    Return PackageManager instance to find global package information. 5.public abstract String getPackageName () 
    Return the name of this application's package. 6.public abstract Resources getResources () 
    Return a Resources instance for your application's package. 7.public abstract SharedPreferences getSharedPreferences (String name, int mode) 
    Retrieve and hold the contents of the preferences file 'name', returning a SharedPreferences through which you can retrieve and modify its values. Only one instance of the SharedPreferences object is returned to any callers for the same name, meaning they will see each other's edits as soon as they are made.8.public final String getString (int resId) 
    Return a localized string from the application's package's default string table.9.public abstract Object getSystemService (String name) 
    Return the handle to a system-level service by name. The class of the returned object varies by the requested name. Currently available names are: 还有很多有用的方法,具体不一一列举。详情请参考文档,反正Context很有用。本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhangqijie001/archive/2010/09/17/5891682.aspx
      

  7.   

    [Android] Context应该怎么写? 
    http://www.cnblogs.com/xiaowenji/archive/2010/12/08/1900449.html如果想要弹出一个AlertDialog,要写如下的代码 view sourceprint?1 AlertDialog.Builder alert =new AlertDialog.Builder(this);  2 alert.setTitle("Warning");  3 alert.setMessage("Wrong time!");  4 alert.show();  
    这里构造方法的原型是AlertDialog.Builder(Context arg) 需要一个Context类的对象作为参数,一般我们都在Activity里写,所以用this,表示在当前的会话中弹出AlertDialog。 
    在我的一个程序里,我自定义了一个接口Public interface CustomPickerListener,在实现这个接口的方法时我需要弹出来一个AlertDialog,这里,参数表里填写this的话会提示错误:The constructor AlertDialog.Builder(new CustomPickerListener(){}) is undefined.
    其实这个地方写this很明显是错误的,但是要写什么才能达成目的呢?
    官方文档上对context的解释是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.
    于是我就试着写上了我程序的 包.目标类.this ,如下 view sourceprint?1 AlertDialog.Builder alert =new AlertDialog.Builder(com.android.alcoholtest.AlcoholTest.this); 然后就成功了
      

  8.   

    Android中Activity共享变量的另一方法:Application context
    http://www.cnmsdn.com/html/201005/1273856212ID4727.html
    Android中在不同Activity中传递变量,通常使用Intent中Bundle添加变量的操作方法。  view plaincopy to clipboardprint?  Intent intent = new Intent();  intent.setClass(A.this, B.class);  Bundle bundle = new Bundle();  bundle.putString("Info", "Information");  intent.putExtras(bundle);  startActivity(intent);  Intent  intent = new Intent();  intent.setClass(A.this, B.class);  Bundle bundle = new Bundle();  bundle.putString("Info", "Information");  intent.putExtras(bundle);  startActivity(intent);  不过在多个Activity中经常使用同一变量时,使用Bundle则比较麻烦,每次调用Activity都需要设置一次。  如想在整个应用中使用,在java中一般是使用静态变量,而在android中有个更优雅的方式是使用Application context。  新建一个类,继承自Application  view plaincopy to clipboardprint?  class MyApp extends Application {  private String myState;  public String getState() {  return myState;  }  public void setState(String s) {  myState = s;  }  }  class MyApp extends  Application {  private String myState;  public String getState() {  return myState;  }  public void setState(String s) {  myState = s;  }  }  在AndroidManifest.xml的application加个name属性就可以了,如下面所示:  view plaincopy to clipboardprint?    < p>   android:name=".MyApp" android:icon="@drawable/icon"  android:label="@string/app_name">  使用时:  view plaincopy to clipboardprint?  class Blah extends Activity {@Override  public void onCreate(Bundle b){  ...  MyApp appState = ((MyApp)getApplicationContext());  String state = appState.getState();  ...  }  }  class Blah extends  Activity {  @Override  public void onCreate(Bundle b){  ...  MyApp appState = ((MyApp)getApplicationContext());  String state = appState.getState();  ...  }  }  英文引用:http://stackoverflow.com/questions/708012/android-how-to-declare- global-variables  The more general problem you are encountering is how to save stateacross several Activities and all parts of your application. A staticvariable (for instance, a singleton) is a common Java way of achievingthis. I have found however, that a more elegant way in Android is toassociate your state with the Application context.  --如想在整个应用中使用,在java中一般是使用静态变量,而在android中有个更优雅的方式是使用Application context。  As you know, each Activity is also a Context, which is informationabout its execution environment in the broadest sense. Your applicationalso has a context, and Android guarantees that it will exist as asingle instance across your application.  --每个Activity 都是Context,其包含了其运行时的一些状态,android保证了其是single instance的。  The way to do this is to create your own subclass of android.app.Application,and then specify that class in the application tag in your manifest.Now Android will automatically create an instance of that class andmake it available for your entire application. You can access it fromany context using the Context.getApplicationContext() method (Activityalso provides a method getApplication() which has the exact sameeffect):  --方法是创建一个属于你自己的android.app.Application的子类,然后在manifest中申明一下这个类,这是 android就为此建立一个全局可用的实例,你可以在其他任何地方使用Context.getApplicationContext()方法获取这个实例,进而获取其中的状态(变量)。
      

  9.   

    android共享全局数据的问题http://topic.csdn.net/u/20110215/20/e15e88bc-ac0e-4055-80a5-cbcbc3cc0439.html?45440今天下午遇到画面间传递参数的问题,经过指点知道可以用重写Application来保存全局的数据然后根据帖子上的实例http://www.eoeandroid.com/thread-30257-1-1.html做了一个小例子,却总是报ClassCastException,错误在android.app.Application求高手指点 代码如下appTest.java
    public class appTest extends Activity {
      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      ((App)getApplication()).setDemo("sss");
      String demo = ((App)getApplication()).getDemo();   
      }
    }重写的Application文件
    App.javaimport android.app.Application;public class App extends Application{
        
    private String demo;public String getDemo() {
    return demo;
    }public void setDemo(String demo) {
    this.demo = demo;
    }
    }AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.appTest"
      android:versionCode="1"
      android:versionName="1.0">
      <application android:icon="@drawable/icon" android:label="@string/app_name">
      <activity android:name=".appTest"
      android:label="@string/app_name">
      <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      </activity>
      </application>
      <uses-sdk android:minSdkVersion="10" />
      <application android:name=".App"
    android:icon="@drawable/icon"   
    android:label="@string/app_name">
      </application>   App.java和appTest.java都在同一个包里com.appTest求高手指点!~!~!~小弟先谢谢了
    //---------------------------------
    问题解决了 是AndroidManifest配置的不对 把android:name=".App"放到第一个application配置里就好了
      

  10.   

    android中共享全局数据的方法http://www.eoeandroid.com/thread-30257-1-1.html
    我们在平时的开发中,有时候可能会需要一些全局数据,来让应用中的所有Activity和View都能访问到,大家在遇到这种情况时,可能首先会想到自己定义一个类,然后创建很多静态成员,不过android已经为我们提供了这种情况的解决方案,下面就来介绍一下:     在Android中,有一个名为Application的类,我们可以在Activity中使用getApplication(),方法来获得,它是代表我们的应用程序的类,使用它可以获得当前应用的主题,资源文件中的内容等,这个类更灵活的一个特性就是可以被我们继承,来添加我们自己的全局属性。例如我们在开发一个游戏应用,需要保存分数,那么我们就可以继承Application,代码如下:public class GameApplication extends Application {    private int score;        public int getScore() {        return score;    }    public void setScore(int score) {        this.score = score;    }}
    复制代码
    这样我们就扩展了自己的属性,不过还没有结束,另外一个比较关键的一部,是需要在androidManifest.xml文件中将我们扩展后的Application类指定上去,例如下面的代码:    <application    android:name=".GameApplication"     android:icon="@drawable/icon"     android:label="@string/app_name">
    复制代码
    这样指定好之后,我们的自定义Application就算完成了,然后我们可以很方便的在任何Activity和View中来获取我们的分数属性,代码如下:在Activity中://设置分数((GameApplication)getApplication()).setScore(100)
    复制代码
    //获取分数((GameApplication)getApplication()).getScore();
    复制代码
    在View中:((GameApplication)getContext().getApplicationContext()).getScore()
    复制代码 
      

  11.   

    [小技巧]在任意位置获取应用程序Context - [Android学习笔记]http://eshock.blogbus.com/logs/65414382.htmlAndroid程序中访问资源时需要提供Context,一般来说只有在各种component中(Activity, Provider等等)才能方便的使用api来获取Context, 而在某些工具类中要获取就很麻烦了。为此,我们可以自定义一个Application类来实现这种功能。import android.app.Application;public class MyApplication extends Application {
        private static MyApplication instance;    public static MyApplication getInstance() {
            return instance;
        }    @Override
        public void onCreate() {
            // TODO Auto-generated method stub
            super.onCreate();
            instance = this;
        }
    }然后在manifest中<application>中加入name="mypackage.MyApplication"就可以在任意类中使用MyApplication.getInstance()来获取应用程序Context了。
      

  12.   

    Android获取其他包的Context实例然后干坏事http://chroya.javaeye.com/blog/761441
    Android中有Context的概念,想必大家都知道。Context可以做很多事情,打开activity、发送广播、打开本包下文件夹和数据库、获取classLoader、获取资源等等。如果我们得到了一个包的Context对象,那我们基本上可以做这个包自己能做的大部分事情。          那我们能得到吗?很高兴的告诉你,能!
          Context有个createPackageContext方法,可以创建另外一个包的上下文,这个实例不同于它本身的Context实例,但是功能是一样的。 
          这个方法有两个参数:
    1。packageName  包名,要得到Context的包名
    2。flags  标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。CONTEXT_INCLUDE_CODE的意思是包括代码,也就是说可以执行这个包里面的代码。CONTEXT_IGNORE_SECURITY的意思是忽略安全警告,如果不加这个标志的话,有些功能是用不了的,会出现安全警告。 
          下面给个小例子,执行另外一个包里面的某个类的方法。
          另外一个包的包名是chroya.demo,类名Main,方法名print,代码如下: Java代码 
    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);   
        }   
    }  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方法的代码块如下: Java代码 
    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 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");       ok,这样,我们就调用了chroya.demo包的Main类的print方法,执行结果,打印出了Hello。       怎么样,这只是一个调用其他包的代码的例子,我们获取到Context,还可以做很多事情,当然,题目所说的坏事,还是不要做为好。 
      

  13.   

    这样理解就很简单了:一个APK进程只有一个Context: 这个Context就是ApplicationContext,从Context继承过来。ApplicationContext可以看做是针对整个系统的全局处理接口,因为:
    它负责和系统服务打交道
    RPC通信由他通过那些XXXServiceManager和XXXService来处理。其他一些模块,比如Activity,Service等,也是从Context继承而来的。
    比如Acitivity在attach到主线程(ActivityThread)时,会用ApplicationContext来初始化这个Activity,这样就OK了。比如Activity中StartService,调用过程如下:
    Activity.StartService
    (Activity继承自ContextWraper,实际会执行 ContextWraper中的)
    public ComponentName startService(Intent service) {
            return mBase.startService(service);
        }这里面的mBase实际就是ApplicationContext
    ApplicationContext中的实现如下:
    @Override
        public ComponentName startService(Intent service) {
            try {
                ComponentName cn = ActivityManagerNative.getDefault().startService(
                    mMainThread.getApplicationThread(), service,
                    service.resolveTypeIfNeeded(getContentResolver()));
                if (cn != null && cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                }
                return cn;
            } catch (RemoteException e) {
                return null;
            }
        }通过系统服务来做的。总之:context就是将这些系统服务提供的功能,完美的包装起来了,其中的RPC过程,用户无需关心。好像这些功能就是在那,自己可以随便使用(要知道跨进程通信和调用,是非常难和麻烦的事情)。
      

  14.   

    晕了,看的我,不过还是要慢慢的看,Context ,希望从现在能够明白点。
      

  15.   

    其实,说白了,学过JavaWeb的应该知道域,我感觉这个Context就跟域相似,存在于整个应用中
      

  16.   

    为何不看官方文档?Context Class Overview:
    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. 
      

  17.   

    五月的风将的很彻底,让人很清楚明白了Context使用的整个过程
    楼主将Context的用法阐述的也很完善
    好贴 
      

  18.   

    Context是运行时对象引用的容器,大多是一个中间类,里面在完成一件事情中主要对象的引用。作用:建立一个背景或场景,将上下文中相关的对象都引用进一个场景,一般是一个大类,然后方便大家引用、传递,有些类似于中间都模式。
      

  19.   

    楼主分析的很好,MARK了!以后慢慢学习!
      

  20.   

    接触android没多久,看了这些贴!给一点我自己的理解!不对的望指点!
    我觉得 context就是一个实例对象、一个对象句柄,再往下看也就是this指针,从汇编的角度来看就是SP了!实际上他们是一个东西。以windows的程序来理解,一个应用程序有一个实例、一个动态库也有一个实例、对于类来说一个类对象也可以看着一个实例。我认为context跟对象句柄和this指针就是一个东西。我把context认为是对this指针的一个封装。你如果通过实例对象引用函数和用this指针应用函数的SP地址其实是一样的。但为什么还会有context出现呢?我认为只是为了安全性考虑!在C++中,如果你this指针引用有问题,整个程序会马上崩掉、而如果你是用实例或者是对象句柄只是你引用的函数达不到你想要的结果,而程序不会崩掉。我想是因为你引用对象时做了处理,不会让你处理一个非法指针。
      

  21.   

    好文章啊,仔细看完之后差不多就全理解了对于每个运行中的Android Application,存在唯一的一个Application Context.
    然后,对于每个Activity或者Service,有一个基于Application Context的Context.其中后者保留对前者的应用,可使用 getApplicationContext()来得到前者.而那些View之类的,则保留对Activity Context的引用.
      

  22.   

    找了半天有关context的分析,很混乱,看到楼主牛逼人的帖子之后,顿悟了许多,感谢楼主。
      

  23.   

    到了一个button的onClick(View view)等方法时,我们用this时就会报错,所以我们可能使用ActivityName.this来解决     不太明白,试了,但是没解决
      

  24.   

    不错不错,终于搞懂context了!