Android Context 上下文 你必须知道的一切

今天被问到了关于Context的一些问题。发现自己关于这部分还是不是很清晰,然后发现洋神博客里有一篇讲的很好 很详细。我反正是看懂了,我觉得我再写 也不会比这个更清楚了,所以转过来。

http://blog.csdn.net/lmj623565791/article/details/40481055,本文出自:【张鸿洋的博客】

1、Context概念

其实一直想写一篇关于Context的文章,但是又怕技术不如而误人子弟,于是参考了些资料,今天准备整理下写出来,如有不足,请指出,参考资料会在醒目地方标明。
Context,相信不管是第一天开发Android,还是开发Android的各种老鸟,对于Context的使用一定不陌生~~你在加载资源、启动一个新的Activity、获取系统服务、获取内部文件(夹)路径、创建View操作时等都需要Context的参与,可见Context的常见性。大家可能会问到底什么是Context,Context字面意思上下文,或者叫做场景,也就是用户与操作系统操作的一个过程,比如你打电话,场景包括电话程序对应的界面,以及隐藏在背后的数据;
但是在程序的角度Context又是什么呢?在程序的角度,我们可以有比较权威的答案,Context是个抽象类,我们可以直接通过看其类结构来说明答案:
这里写图片描述
可以看到Activity、Service、Application都是Context的子类;
也就是说,Android系统的角度来理解:Context是一个场景,代表与操作系统的交互的一种过程。从程序的角度上来理解:Context是个抽象类,而Activity、Service、Application等都是该类的一个实现。
在仔细看一下上图:Activity、Service、Application都是继承自ContextWrapper,而ContextWrapper内部会包含一个base context,由这个base context去实现了绝大多数的方法。
先扯这么多,有能力了会从别的角度去审视Context,加油~

2、Context与ApplicationContext

看了标题,千万不要被误解,ApplicationContext并没有这个类,其实更应该叫做:Activity与Application在作为Context时的区别。嗯,的确是这样的,大家在需要Context的时候,如果是在Activity中,大多直接传个this,当在匿名内部类的时候,因为this不能用,需要写XXXActivity.this,很多哥们会偷懒,直接就来个getApplicationContext。那么大家有没有想过,XXXActivity.this和getApplicationContext的区别呢?
XXXActivity和getApplicationContext返回的肯定不是一个对象,一个是当前Activity的实例,一个是项目的Application的实例。既然区别这么明显,那么各自的使用场景肯定不同,乱使用可能会带来一些问题。
下面开始介绍在使用Context时,需要注意的问题。

3、引用的保持

大家在编写一些类时,例如工具类,可能会编写成单例的方式,这些工具类大多需要去访问资源,也就说需要Context的参与。
在这样的情况下,就需要注意Context的引用问题。
例如以下的写法:

package com.mooc.shader.roundimageview;  import android.content.Context;  public class CustomManager  
{  private static CustomManager sInstance;  private Context mContext;  private CustomManager(Context context)  {  this.mContext = context;  }  public static synchronized CustomManager getInstance(Context context)  {  if (sInstance == null)  {  sInstance = new CustomManager(context);  }  return sInstance;  }  //some methods   private void someOtherMethodNeedContext()  {  }  
}  

对于上述的单例,大家应该都不陌生(请别计较getInstance的效率问题),内部保持了一个Context的引用;
这么写是没有问题的,问题在于,这个Context哪来的我们不能确定,很大的可能性,你在某个Activity里面为了方便,直接传了个this;这样问题就来了,我们的这个类中的sInstance是一个static且强引用的,在其内部引用了一个Activity作为Context,也就是说,我们的这个Activity只要我们的项目活着,就没有办法进行内存回收。而我们的Activity的生命周期肯定没这么长,所以造成了内存泄漏。
那么,我们如何才能避免这样的问题呢?
有人会说,我们可以软引用,嗯,软引用,假如被回收了,你不怕NullPointException么。
把上述代码做下修改:

public static synchronized CustomManager getInstance(Context context)  {  if (sInstance == null)  {  sInstance = new CustomManager(context.getApplicationContext());  }  return sInstance;  } 

这样,我们就解决了内存泄漏的问题,因为我们引用的是一个ApplicationContext,它的生命周期和我们的单例对象一致。
这样的话,可能有人会说,早说嘛,那我们以后都这么用不就行了,很遗憾的说,不行。上面我们已经说过,Context和Application Context的区别是很大的,也就是说,他们的应用场景(你也可以认为是能力)是不同的,并非所有Activity为Context的场景,Application Context都能搞定。
下面就开始介绍各种Context的应用场景。

4、Context的应用场景

这里写图片描述
大家注意看到有一些NO上添加了一些数字,其实这些从能力上来说是YES,但是为什么说是NO呢?下面一个一个解释:
数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task。一般情况不推荐。
数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用。
数字3:在receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视)
注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。

好了,这里我们看下表格,重点看Activity和Application,可以看到,和UI相关的方法基本都不建议或者不可使用Application,并且,前三个操作基本不可能在Application中出现。实际上,只要把握住一点,凡是跟UI相关的,都应该使用Activity做为Context来处理;其他的一些操作,Service,Activity,Application等实例都可以,当然了,注意Context引用的持有,防止内存泄漏。

5、总结

好了,到此,Context的分析基本完成了,希望大家在以后的使用过程中,能够稍微考虑下,这里使用Activity合适吗?会不会造成内存泄漏?这里传入Application work吗?

转载于:https://www.cnblogs.com/codenoodles/p/6421151.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/490368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中mysqldb模块_python中MySQLdb模块用法实例

本文实例讲述了python中MySQLdb模块用法。分享给大家供大家参考。具体用法分析如下:MySQLdb其实有点像php或asp中连接数据库的一个模式了,只是MySQLdb是针对mysql连接了接口,我们可以在python中连接MySQLdb来实现数据的各种操作。python连接m…

g++编译多个文件

假设现在有一个add.cpp,add.h,main.cpp这三个文件,文件内容如下: add.cpp: add.h: main.cpp: 我需要将add.cpp和main.cpp这两个文件进行编译,有以下两种方法: g -c add.cpp g -c main.cpp g main.o add.o -o test ./test 第二种…

【数字孪生】工业互联网和数字孪生

来源:产业智能官《崛起的超级智能》一书主要阐述当今天人类为人工智能的春天到来而兴奋,为人工智能是否超越人类而恐慌的时候,一个更为庞大、远超人类预期的智能形态正在崛起,种种迹象表明50年来,互联网正在从网状结构…

javascript数组扁平化处理

最近看jQuery源码$.map方法的实现,返回值利用了一个扁平化处理 return ret.concat.apply( [], ret ) 这有个疑问,不知道为什么不直接返回ret 根据这个返回值处理,推测ret可能不是一阶数组,例如[1,2,[3,4]]这样的; var ret [1,2,[…

k折交叉验证法python实现_Jason Brownlee专栏| 如何解决不平衡分类的k折交叉验证-不平衡分类系列教程(十)...

作者:Jason Brownlee编译:Florence Wong – AICUG本文系AICUG翻译原创,如需转载请联系(微信号:834436689)以获得授权在对不可见示例进行预测时,模型评估涉及使用可用的数据集来拟合模型,并评估其表现性能。…

linux的find命令满屏权限不够提示

用find命令是如果是普通用户通常会输出一堆“权限不够”的提示,这会影响到我们找出有用的信息,为了将这些错误忽略,可以采用重定向: find / -name add.h 2> /dev/null

AI“换脸”打开潘多拉魔盒,如何应对?

来源:科学网近日,一款名为“ZAO”的换脸APP引发舆论关注。用户上传照片,就可以把影视剧主角的脸替换成用户自己的脸。在过把“明星瘾”的同时,也让大众关注到“换脸”带来的个人信息泄露风险。信息时代,“脸面”不仅仅…

stm32超声波测距代码_超声波模块另类用法,悬浮,你也能做到

今天,给大家介绍一个「超酷的DIY声波悬浮」研究项目。虽然超声波悬浮,不能像磁悬浮那样悬浮比较重的物品。不过能把小泡沫球、水滴或者蚂蚁这样的小物体悬浮起来也是很有意思的。制作这样一个简易的超声波悬浮器并不需要多少成本,而且材料很容…

vim:去掉响铃

vim在移动字符出界&#xff08;上下左右&#xff09;包括按<ESC>建都会响铃&#xff0c;有时候真的很烦。 在网上搜了一下&#xff0c;原来是visualbell来控制的&#xff0c;在vim里使用命令:help visualbell&#xff0c;原来禁止命令是:novb 好了&#xff0c;在.vimrc文…

【AI战略】2019年美国国家人工智能战略报告(中文翻译版)

来源&#xff1a;AI城市智库人工智能(AI)拥有巨大的希望&#xff0c;几乎可以使社会的各个方面受益&#xff0c;包括经济&#xff0c;医疗保健&#xff0c; 安全&#xff0c;法律&#xff0c;运输&#xff0c;甚至技术本身。2019年2月11日&#xff0c;总统签署了行政命令13859…

函数对象

若一个类重载了运算符“&#xff08;&#xff09;”&#xff0c;则该类的对象就成为函数对象。函数对象可以用于标准库算法。函数对象和函数指针很相似&#xff0c;但也有区别。当函数对象使用模板时可以赋值给函数指针。 #include <iostream #include <vector> #incl…

linux vim下删除一行和多行

删除一行&#xff1a; 在命令模式下将光标移至要删除的行位置&#xff0c;按下dd 删除n行&#xff1a; 假设要删除5行&#xff0c;在命令模式下将光标移至要删除的行的开始位置&#xff0c;按下5dd

python如何查看有什么模块_在python中如何查看模块功能

在python中查看模块功能的方法&#xff1a;1、在python命令行输入help()函数进入help帮助文档界面&#xff1b;2、键入【modules】列出当前所有安装的模块&#xff1b;3、键入相应的模块名称即可得到该模块的功能信息。python的一个优势是有着大量自带和在线的模块(module)资源…

拍下首张黑洞照片的团队获300万美元奖金:2020年科学突破奖揭晓

来源&#xff1a;科学突破奖科学突破奖2019 年 9 月 5 日&#xff0c;2020 年度突破奖&#xff08;Breakthrough Prize&#xff09;揭晓。突破奖&#xff0c;又被誉为“科学界的奥斯卡”&#xff0c;现已经入第八个年头。突破奖每年都会表彰在生命科学&#xff0c;基础物理学和…

linux vim复制和粘贴

复制&#xff1a; 在命令行模式下将光标移至要复制的行&#xff0c;按下yy即可复制该行&#xff0c;如果要复制5行&#xff0c;按下5yy即可复制从光标这行开始的5行 粘贴&#xff1a; 在命令行模式下将光标移至粘贴处&#xff0c;按下p

C#获取ip的示例

界面 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms; namespace TestIP{ public partial class Form1 : Form { public Form1() { InitializeComponent()…

硬盘序列号查询软件_【西数硬盘购买指南】干货——西数移动硬从购买到验证体会心得...

玩摄影有两年多了&#xff0c;所以照片和视频越来越多。上个月618活动&#xff0c;有入手了一块移动硬盘。买多是&#xff1a;西部数据My Passport Ultra移动硬盘4T下面从购买到验证全过程来说图片来源网络图片来源网络一、天猫截图上一篇文章&#xff1a;【希捷硬盘购买指南】…

多角度解析特斯拉电动车技术到底领先了多少?|厚势

来源&#xff1a;Astroys厚势按&#xff1a;不管是豪华车、传统车还是新造车势力造的电动车&#xff0c;都以对标特斯拉为荣。是什么让特斯拉成为电动车的图腾&#xff1f;特斯拉的电动车技术到底领先多少&#xff1f;本文 8000 余字&#xff0c;多个角度进行分析解读。在人们的…

Logistic回归的牛顿法及DFP、BFGS拟牛顿法求解

牛顿法 1 # coding:utf-82 import matplotlib.pyplot as plt3 import numpy as np4 5 def dataN(length):#生成数据6 x np.ones(shape (length,3))7 y np.zeros(length)8 for i in np.arange(0,length/100,0.02):9 x[100*i][0]110 x[100*i][1]…

vim复制一个文件的多行到另一个文件

vim打开一个文件后复制多行&#xff0c;退出这个文件之后&#xff0c;打开另一个文件想复制到这个文件&#xff0c;却发现在上一个文件中复制的内容不见了 所以vim复制一个文件的多行到另一个文件的正确做法是要同时打开两个文件 比如要把add.cpp的内容复制到main.cpp 首先v…