Android下Context,Activity,Application之间有什么区别
2016-12-19 · 传媒培训、投行培训、实习内推
我发现这个表超级有用的决定何时使用不同类型的上下文:
应用程序可以从这里开始一个活动,但它需要一个新的任务被创建。 这可能适合特定的用例,但是可以创建标准栈行为一般不建议在您的应用程序,或者一种不错的做法。
这是合法的,但通货膨胀将使用默认主题您正在运行的系统,而不是在应用程序中定义的。
允许如果接收者是null,用于获取的当前值的广播,在安卓4.2及以上。
外网译文:
上下文对象是如此普遍,如此频繁的传递,很容易创建一个情况你没有意愿。 加载资源,推出一个新的活动,获得一个系统服务,内部文件路径,所有需要创建视图上下文(这是没有开始的完整列表!)来完成这项任务。 我想做的就是为你提供一些见解上下文作品和一些技巧,这些技巧将(希望)允许您在应用程序中更有效地利用它。
上下文类型
并不是所有的上下文实例都是平等的。 根据Android应用程序组件上下文你可以访问略有不同:
应用程序——是一个单例实例中运行您的应用程序的过程。 它可以通过访问方法getApplication()从一个活动或服务getApplicationContext()从任何其他对象继承上下文。 无论它如何访问,你总是会收到相同的实例从内部流程。
活动/服务——继承ContextWrapper实现相同的API,但是代理所有的方法调用一个隐藏的内部上下文上下文实例,也被称为它的基地。 每当框架创建一个新的活动或服务实例,它还创建了一个新的ContextImpl实例做所有组件将包装的重任。 每个活动或服务,及其相应的基础背景,是独一无二的每个实例。
BroadcastReceiver——不是一个上下文本身,而是通过一个框架上下文在onReceive()每次新的广播事件出现的原因。 这个例子是一个ReceiverRestrictedContext有两个主要功能残疾;调用registerReceiver()和bindService()。 这两个函数不允许从内部现有的BroadcastReceiver.onReceive()。 每次一个广播接收器流程,上下文交给一个新实例。
内容提供者——也不是上下文但给出了一个创建时,可以通过访问getContext()。 如果ContentProvider运行本地调用者(即同一应用程序的过程),那么这个单会返回相同的应用程序。 然而,如果两个单独的进程,这将是一个新创建的实例代表包中运行的提供者。
保存引用
我们需要解决的第一个问题来自储蓄的引用上下文在一个对象或类的实例的生命周期,超出你救了。 例如,创建一个自定义需要的单例上下文加载资源或访问ContentProvider,并保存当前活动或服务的引用的单例。
坏的单例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
公共 类 CustomManager {
私人 静态 CustomManagersInstance;
公共 静态 CustomManagergetInstance(上下文上下文) {
如果 (sInstance = = 零) {
sInstance = 新 CustomManager(上下文);
}
返回 sInstance;
}
私人 上下文mContext;
私人 CustomManager(上下文上下文) {
mContext = 上下文;
}
}
这里的问题是我们不知道上下文来自,不安全持有对象的引用如果它最终成为一个活动或一个服务。 这是一个问题,因为单是由一个单一的静态引用在封闭类。 这意味着我们的对象,和所有其他对象引用它,永远不会被垃圾收集。 如果这上下文是一个活动,我们会有效地持有人质在内存中所有与它相关的观点和其他潜在的大对象,创建一个泄漏。
为了防止这一点,我们修改单总是参考应用程序上下文:
更好的单例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
公共 类 CustomManager {
私人 静态 CustomManagersInstance;
公共 静态 CustomManagergetInstance(上下文上下文) {
如果 (sInstance = = 零) {
/ /总是通过在应用程序上下文
sInstance = 新 CustomManager(上下文。getApplicationContext());
}
返回 sInstance;
}
私人 上下文mContext;
私人 CustomManager(上下文上下文) {
mContext = 上下文;
}
}
现在我们并不重要上下文来自,因为参考我们是安全的。 应用程序上下文本身就是一个单,所以我们没有泄露任何通过创建另一个静态引用。 另一个很好的例子,这可以出现的地方保存一个引用上下文从正在运行的后台线程或等待处理程序。
那么,为什么我们不能总是只是引用应用程序上下文? 以中间人的方程,,,永远不必担心创造泄漏? 答案,我在引言中提到,是因为一个上下文不等于另一个。
上下文的能力
您可以安全地采取共同行动与给定上下文对象取决于最初是从哪里来的。 下面是一个表的常见应用程序将接收的地方上下文,在每一种情况下是很有用的:
应用程序
活动
服务
内容提供者
BroadcastReceiver
显示一个对话框 没有 是的 没有 没有 没有
开始一个活动 没有1 是的 没有1 没有1 没有1
布局的通货膨胀 没有2 是的 没有2 没有2 没有2
启动一个服务 是的 是的 是的 是的 是的
绑定到一个服务 是的 是的 是的 是的 没有
发送一个广播 是的 是的 是的 是的 是的
注册BroadcastReceiver 是的 是的 是的 是的 没有3
加载资源值 是的 是的 是的 是的 是的
应用程序可以从这里开始一个活动,但它需要一个新的任务被创建。 这可能适合特定的用例,但是可以创建标准栈行为一般不建议在您的应用程序,或者一种不错的做法。
这是合法的,但通货膨胀将使用默认主题您正在运行的系统,而不是在应用程序中定义的。
允许如果接收器零,用于获取的当前值的广播,在安卓4.2及以上。
用户界面
从看着前面的表中可以看到,有很多功能的应用程序上下文是适合处理不当;他们与UI相关的工作。 事实上,只有实现装备来处理所有与UI相关的任务活动,其他实例票价差不多在所有类别。
幸运的是,这三个动作是一个应用程序并没有任何地方做一个活动的范围之外,就像框架是故意这样设计的。 试图展示一个对话框创建应用程序上下文的引用,或者开始一个活动的应用程序上下文将抛出一个异常且应用程序崩溃…一个强大的指示器出事了。
不太明显的问题是膨胀布局。 如果你读过我的最后一块布局的通货膨胀,你已经知道它可能是一个有点神秘的过程和一些隐藏行为,使用正确的上下文与另一个的行为。 而框架不会抱怨,将返回一个完美的从一个视图层次LayoutInflater创建应用程序上下文,主题和风格的应用程序将不考虑过程。 这是因为活动是唯一的上下文清单中定义的主题实际上是连接。 任何其他实例将使用系统默认主题膨胀你的视图,导致显示输出你可能没想到。
这些规则的十字路口
总是,有人会到达这两个规则冲突的结论。 有一个案件在长期引用的应用程序当前的设计必须保存,我们必须拯救一个活动因为我们想要完成的任务包括UI的操作。 如果是这样的话,我就会劝你重新考虑你的设计,因为这将是一个教科书的实例战斗框架。
经验法则
在大多数情况下,使用上下文直接提供给你从封闭组件在工作。 您可以安全地举行的引用,只要引用不超越该组件的生命周期。 一旦你要保存的引用上下文从一个对象的生活超出你的活动或服务,即使暂时,开关,参考您保存到应用程序上下文。
2016-11-23 · 百度知道合伙人官方认证企业
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。
从上可知一下三点即:
1、它描述的是一个应用程序环境的信息,即上下文。
2、该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类(后面咱们会讲到是ContextIml类)。
3、通过它咱们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent信息等。