Context那些事儿

来源:互联网 发布:制作头像软件 编辑:程序博客网 时间:2024/05/18 00:05

今天我们来聊聊Context那些事儿。

首先,Context是个啥?
字面意思上,很容易理解:上下文。
再具体一点,看下sdk中对它的描述:
Interface to global information about an application environment 应用环境的整体信息的接口。
这它喵的一点用处都没有啊!

所以我们来看一下这货的源码:

public abstract class Context {    /** Return an AssetManager instance for your application's package. */    public abstract AssetManager getAssets();    /** Return a Resources instance for your application's package. */    public abstract Resources getResources();    /** Return PackageManager instance to find global package information. */    public abstract PackageManager getPackageManager();    /** Return a ContentResolver instance for your application's package. */    public abstract ContentResolver getContentResolver();    public abstract Looper getMainLooper();    public abstract Context getApplicationContext();}

看到第一行我就给跪了,这货居然还是个抽象类,再仔细看下里面的方法,getResources(),getPackageManager()等等,咦?是不是有点眼熟啊,这些方法在哪里见过。

是的,Activity里面就有这些方法。
所以你应该猜到了:Activity是Context的一个子类

来看下Activity的源码:

public class Activity extends ContextThemeWrapper

而ContextThemeWrapper:

public class ContextThemeWrapper extends ContextWrapper

最后,ContextWrapper继承自Context:

public class ContextWrapper extends Context

这就是为啥,我们通常会在Activity里这么写:

public class MainActivity extends Activity {    private Context mContext;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mContext = this;        ...    }

然而你以为到这儿就结束了吗?当然不是,如果是的话我就不会写这篇博客了。。。

我们再看一下Application的源码:

public class Application extends ContextWrapper

还有Service的源码:

public abstract class Service extends ContextWrapper

所以。。。Application和Service也是Context的子类。

这意味着什么?这意味着我们可以这么写:

public class DemoApplication extends Application {    private Context mContext;    @Override    public void onCreate() {        super.onCreate(savedInstanceState);        mContext = this;        ...    }

以及这么写:

public class DemoService extends Service {    private Context mContext;    @Override    public void onCreate() {        super.onCreate(savedInstanceState);        mContext = this;        ...    }

我估计这时候你已经懵逼了。。。
现在我们有3个Context了,这看起来是个好事儿,因为貌似我们的选择多了,但是也是个坏事儿,因为你不知道啥时候该用哪个了。

我们再来举个例子,写一个UserManager的类,并把它设置成单例(通常我们并不想要多个Manager的实例同时存在),因为这个类要用到SharedPreferences,所以我们需要一个Context:

public class UserManager {    private static Context mContext;    private static UserManager instance = new UserManager();    private UserManager() {    }    public static UserManager getInstance(Context context) {        mContext = context;        return instance;    }

看起来有问题吗?
你知道传进来的这个Context,究竟是哪种吗?Activity? Service?还是Application?
有童鞋可能会说了,管这个干啥,给啥用啥呗。
但是我们仔细想下,如果这个是Activity的Context,那是不是意味着,这个Activity是不能被释放掉的,因为我们有地方在使用Activity的引用,而使用这个引用的地方是全局的单例,它的生命周期,是整个app的生命周期。然后顺带着,因为Activity没有释放掉,所以Activity里面的各种view,各种变量都不会被释放掉。
如果我们的代码里充斥着这种引用,那你会有很多个Activity无法释放掉,结果是什么呢,你的app需要占用大量的内存,或者内存溢出,crash了。

那Context还就不能用了???
当然不是。你可以用Application的Context。
因为Application本身就是单例的,而且它的生命周期,跟app的生命周期是一致的:

public class UserManager {    private static Context mContext;    private static UserManager instance = new UserManager();    private UserManager() {    }    public static UserManager getInstance(Context context) {        mContext = context.getApplicationContext();        return instance;    }

好了,之所以指出上面的这个例子,我是想告诉大家,三种Context是有区别的

  • 你可以在Activity里,用Context去show一个dialog,但是Application和Service不行
  • 你可以在Activity里,使用LayoutInflater,但是Application和Service不行(或者说,没有意义)

所以归结起来:

  • 所有对UI的操作,我们都需要使用Activity的Context
  • 绝大多数情况下,自己用自己的的Context
  • 当你需要保存某个Context的引用时,把它转换成Application的Context

参考文章:https://possiblemobile.com/2013/06/context/

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 疫苗在冰箱停电怎么办 哺乳期吃冰的怎么办 冰盒用的时代短怎么办 海尔冰柜冷藏室结冰怎么办 进项价格比销售价格高怎么办 内存卡上锁了怎么办 空调外机漏电怎么办 电饭煲膜掉了怎么办 电饭锅电阻坏了怎么办 电压力锅糊锅怎么办 电压力锅起锅巴怎么办 电饭煲焖饭夹生怎么办 电饭煲开关坏了怎么办 电饭锅按钮坏了怎么办 洗衣机螺丝断了怎么办 冰箱一直响不停怎么办 海尔洗衣机被锁怎么办 美的电磁炉e6怎么办 冰箱门玻璃碎了怎么办 冰箱传感器坏了怎么办 海尔冰箱灯不亮了怎么办 冰箱不出冰块怎么办 电脑系统无法启动怎么办 指纹锁门被反锁怎么办? 冰箱冷藏室不冷怎么办 冰箱冷藏室有水怎么办 电饭煲焖饭不熟怎么办 电饭锅煮饭没熟怎么办 电饭煲的锅掉皮怎么办 锅盖手柄坏了怎么办 高压锅饭煮不熟怎么办 电源关了灯还闪怎么办 饭只煮的半熟怎么办 饭没煮熟半生怎么办 电饭煲煮饭有锅巴怎么办 冰箱制冷声音大怎么办 新冰箱声音大怎么办 西门子冰箱噪音大 怎么办 热水器出热水慢怎么办 热水器出不了水怎么办 手机内存卡存不进东西怎么办