当前位置:首页 » 安卓系统 » android中context

android中context

发布时间: 2023-05-10 22:06:35

‘壹’ Android中,Context,什么是Context

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方法。

‘贰’ Android中,Context,什么是Context

Context对象是如此常见和传递使用,它可能会很容易产生并不是你预期的情形。加载资源、启动一个新的Activity、获取系统服务、获取内部文件路径以及创建view(其实还远不止这些)统统都需要Context对象来完成。我(原文作者)想做的只是给大家提供一些Context是如何工作的见解,以及让大家在应用中更有效的使用Context的技巧。

Context的类型
并不是所有的context实例都是等价的。根据Android应用的组件不同,你访枣兄掘问的context推向有些细微的差别。

Application - 是一个运行在你的应用进程中的单例。在Activity或者Service中,它可以通过getApplication()函数获得,或者人和继承于context的对象中,通过getApplicationContext()方法获得。不管你是通过何种方法在哪里获得的,在一个进程内,你总是获得到同一个实例。

Activity/Service - 继承于ContextWrapper,它实现了与context同样API,但是代理这些方法调用到内部隐藏的Context实例,即我们所知道的基础context。任何时候当系统创建一个新的Activity或者Service实例的时候,它也创建一个新的ContextImpl实例来做所有的繁重的工作。每一个Activity和Service以及其对应的基础context,对每个实例来说都是唯一的。

BroadcastReciver - 它本身不是context,也没有context在它里面,但是每当一个新的广播到达的时候,框架都传递一个context对象到onReceive()。这个context是一个ReceiverRestrictedContext实例,它有两个主要函数被禁掉:registerReceiver()和bindService()。这两个凳核函数在BroadcastReceiver.onReceive()不允许调用。每次Receiver处理一个广播,传递进来的context都是一个新的实例。

ContentProvider - 它本身也不是一个Context,但是它可以通过getContext()函数给你一个Context对象。如果ContentProvider是在调用者的的本地(例如,在同一个应用进程),getContext()将返回的是Application单例。然而,如果调用这和ContentProvider在不同的进程的时候,它将返回一个新创建的实例代表这个Provider所运行的包。

保存引用
第一个我们需要解决问题是,在一个对象或者类内部保存一个context引用,而它生命周期却超过其保存引用的对象的尘迟生命周期。例如,创建一个自定义的单例,它需要一个context来加载资源或者获取ContentProvider,从而保存一个指向当前Activiy或者Service的引用在单例中。

糟糕的单例

[java] view plain
public class CustomManager {
private static CustomManager sInstance;

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

return sInstance;
}

private Context mContext;

private CustomManager(Context context) {
mContext = context;
}
}

这里的问题在于,我们不知道这个context是从哪里来的,并且如果保存一个最终指向的是Activity或者Servece的引用是并不安全的。这是一个问题,是因为一个单例在类的内部维持一个唯一的静态引用,这意味着我们的对象,以及所有其他它所引用的对象,将永远不能被垃圾回收。假如这个Context是一个Activity,我们将保存与这个Activity相关的所有的view以及其他大的对象,从而造成内存泄漏。
为了解决这个问题,我们修改单例永远只是保存Application context:

改善的单例:

[java] view plain
public class CustomManager {
private static CustomManager sInstance;

public static CustomManager getInstance(Context context) {
if (sInstance == null) {
//Always pass in the Application Context
sInstance = new CustomManager(context.getApplicationContext());
}

return sInstance;
}

private Context mContext;

private CustomManager(Context context) {
mContext = context;
}
}

现在这个例子中,我们的Context来自哪里都没有关系,因为我们这里保存引用是安全的。Application Context 本身就是一个单例,所以我们再创建另外一个static引用,不会造成任何内存泄漏。另外一个很好的例子是,在后台线程或者一个等待的Handler中保存Context的引用,也可以使用这样的方法。

为什么我们不能总是引用Application context呢?正如前面说的,引用Application context永远不用担心内存泄漏的问题。问题的答案,就像我在开始的介绍中说的,是因为不同context并不是等价的。

Context的能力
Conext能做的通用操作决定于这个context最初来源于哪里。下表所列的是,在应用中常见的会收到context对象的,以及对应的每种情况,它可以用于哪些地方:

Application
Activity
Service
ContentProvider
BroadcastReceiver

Show a Dialog NO YES NO NO NO
Start an Activity NO1 YES NO1 NO1 NO1
Layout Inflation NO2 YES NO2 NO2 NO2
Start a Service YES YES YES YES YES
Bind to a Service YES YES YES YES NO
Send a Broadcast YES YES YES YES YES
Register BroadcastReceiver YES YES YES YES NO3
Load Resource Values YES YES YES YES YES

注:NO1 表示Application context的确可以开始一个Activity,但是它需要创建一个新的task。这可能会满足一些特定的需求,但是在你的应用中会创建一个不标准的回退栈(back stack),这通常是不推荐的或者不是是好的实践。
NO2 表示这是非法的,但是这个填充(inflation)的确可以完成,但是是使用所运行的系统默认的主题(theme),而不是你app定义的主题。
NO3 在Android4.2以上,如果Receiver是null的话(这是用来获取一个sticky broadcast的当前 值的),这是允许的。

用户界面UI
从前面的表格中可以看到,application context有很多功能并不是合适去做,而这些功能都与UI相关。实际上,只有Activity能够处理所有与UI相关的任务。其他类别的context实例功能都差不多。

幸运的是,在应用中这三种操作基本上都不需要在Activity范围之外进行,这很可能是android框架故意这么设计的。尝试显示一个使用Aplication context创建的Dialog,或者使用Application context开始一个Activity,系统会抛出一个异常,让你的application崩溃,非常强的告诉你某些地方出了问题。

一个并不明显的问题是填充布局(inflating layout)。如果你已经读过了我(原文作者)的上一篇文章Layout inflation,你就已经知道它可能是一个非常神秘过程,伴随一些隐藏的行为。使用正确的context关系到其中的一个行为。当你使用Application context来inflate一个布局的时候,框架并不会报错,并返回一个使用系统默认的主题创建一个完美的view给你,而没有考虑你的applicaiton自定义的theme和style。这是因为Acitivity是唯一的绑定了在manifast文件种定义主题的Context。其他的Context实例将会使用系统默认的主题来inflater你的view。导致显示的结果并不是你所希望的。

规则的路口
可能有些读者已经得出两个规则互相矛盾的结论。可能有些情况下,在某些Application的设计中,我们可能既必须长期保存一个的引用,并且为了完成与UI相关的工作又必须保存一个Activity。如果出现这种情况,我将会强烈建议你重新考虑你的设计,它将是一个很好的“反框架”教材。

经验法则
绝大多数情况下,使用在你的所工作的组建内部能够直接获取的Context。只要这个引用没有超过这个组建的生命周期,你可以安全的保存这个引用。一旦你要保存一个context的引用,它超过了你的Activity或者Service的生命周期范围,甚至是暂时的,你就需要转换你的引用为Application context。

‘叁’ 理解Android中的Context

Context 是一个抽像类。通常解释叫上下文,或叫环境。

打个比方:Context 好比是一个手的类,每个人的手是不一样的。手可稿哗高以有很多动作。  手可以使用各种工芦者具(如键尺刀、枪、棒、、、)。

一个安卓APP的Context 的数量=activity数+service数+application数

大多数Context子类所用到的方法都是Context提供的。

‘肆’ 怎样了解android中的context

Android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中常用两种context,一种和态是application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。
区别联系:
public class MyActivity extends Activity {
public void method() {
mContext = this; // since Activity extends Context
mContext = getApplicationContext();
mContext = getBaseContext();
}
}
this 是Activity 的实例,扩展了Context,其生命周期是Activity 创建到销毁。getApplicationContext()返回应用的上下大辩文,生命周期是整个应用,应用摧毁它才摧毁滚棚缺。Activity.this的context 返回当前activity的上下文,属于activity ,activity摧毁他就摧毁
getBaseContext() 返回由构造函数指定或setBaseContext()设置的上下文,SDK文档很少,不推荐使用
搞清楚了生命周期就会在使用过程中犯错误,比如有一个全局的数据操作类用到了context,这个时候就要getApplicationContext 而不是用ACtivity,这就保证了数据库的操作与activity无关(不会一直引用Activity的资源,防止内存泄漏)

‘伍’ Android中的context是什么东西

Context,中文直译为“上下文”,SDK中对其说明如迅败察下:
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信息等。

‘陆’ Android中,Context,什么是Context

Context可能是Android应用中最常用的元素,而它也可能是最容易误用的。

Context对象是如此常见和传递使用,它可能会很容易产生并不是你预期的情形。加载资源、启动一个新的Activity、获取系统服务、获取内部文件路径以及创建view(其实还远不止这些)统统都需要Context对象来完成。我(原文作者)想做的只是给大家提供一些Context是如何工作的见解,以及让大家在应用中更有效的使用Context的技巧。

Context的类型

并不是所有的context实例都是等价冲铅罩的。根据Android应用的组件不同,你访问的context推向有些细微的差别。

Application - 是一个运行在你的应用进程中的单例。在Activity或者Service中,它可以通过getApplication()函数获得,或者人和继承于context的对象中,通过getApplicationContext()方法获得。不管你是通过何种方法在哪里获得的,在一个进程内,你总是获得到同一个实例。

Activity/Service - 继承于ContextWrapper,它实现了与context同样API,但是代理这些方法调用到内部隐藏的Context实例,即我们所知道的基础context。任何时候当系统创建一个新的Activity或者Service实例的时候,它也创建一个新的ContextImpl实例来做所有的繁重的工作。每一个Activity和Service以散闹及其对应的基础context,对每个实例来说都是唯一的。

BroadcastReciver - 它本身不是context,也没有context在它里面,但是每当一个新的广播到达的时候,框架都传递一个context对象到onReceive()。这个context是一个ReceiverRestrictedContext实例,它有两个主要函数被禁掉:registerReceiver()和bindService()。这两个函激乱数在BroadcastReceiver.onReceive()不允许调用。每次Receiver处理一个广播,传递进来的context都是一个新的实例。

ContentProvider - 它本身也不是一个Context,但是它可以通过getContext()函数给你一个Context对象。如果ContentProvider是在调用者的的本地(例如,在同一个应用进程),getContext()将返回的是Application单例。然而,如果调用这和ContentProvider在不同的进程的时候,它将返回一个新创建的实例代表这个Provider所运行的包。

保存引用

第一个我们需要解决问题是,在一个对象或者类内部保存一个context引用,而它生命周期却超过其保存引用的对象的生命周期。例如,创建一个自定义的单例,它需要一个context来加载资源或者获取ContentProvider,从而保存一个指向当前Activiy或者Service的引用在单例中。

‘柒’ Android中,Context,什么是Context

context其实就是句柄,只不过不像windows一样,每个资源都可以是一个句柄,Android的一个句柄包含了很多全局信息,比如说Activity就是一个句柄。

官方文档的解释是:Context提供了关于应用环境全局信息的接口。它是一个抽象类,它的执行被Android系统所提供。它允许获取以应用为特征的资源和类型。同时启动应用级的操作,如启动Activity,broadcasting和接收intents。

‘捌’ android中context作用

1、Context是一个抽象类,其通用实现在ContextImpl类中。
2、Context:是一个访问application环境全局信息的接口,通过它可以访问application的资源芦卜和相关的类,其主要功能如下:启动Activity启动和停止Service发送广播消息(Intent)注陪顷穗册广播消息(Intent)接收者可以访问APK中各种资源(如Resources和AssetManager等)可以访问Package的相关信息APK的各种权限管理从以上分析可以看出,Context就是一个对APK包无乎判所不知的大管家,大家需要什么,直接问它就可以了。

‘玖’ Android中,Context,什么是Context

当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context。
Context是一个抽象基类,我们通过它访备尺问当前包的资源(getResources、getAssets)和启动其他组件(Activity、Service、Broadcast)以及得到各种服务(getSystemService),当然,通过Context能得到的不仅仅只有上述这些内容。对Context的理解派磨可以来说:Context提供了一个应用的运行环境,在Context的大环境里,应用才可以访问资源,才能完成和其他组件、服务的交互,Context定义了一套基本的功能接口,可以理解为一套规范,而Activity和Service是实现这套规范的子类,这么说也许并不准确,因为这套规范实际是被ContextImpl类统一实现的,Activity和Service只是继承并有选择性地重写了某些规范的尘滚斗实现。

‘拾’ Android中,Context,什么是Context

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。

热点内容
内置存储卡可以拆吗 发布:2025-05-18 04:16:35 浏览:336
编译原理课时设置 发布:2025-05-18 04:13:28 浏览:378
linux中进入ip地址服务器 发布:2025-05-18 04:11:21 浏览:612
java用什么软件写 发布:2025-05-18 03:56:19 浏览:32
linux配置vim编译c 发布:2025-05-18 03:55:07 浏览:107
砸百鬼脚本 发布:2025-05-18 03:53:34 浏览:945
安卓手机如何拍视频和苹果一样 发布:2025-05-18 03:40:47 浏览:742
为什么安卓手机连不上苹果7热点 发布:2025-05-18 03:40:13 浏览:803
网卡访问 发布:2025-05-18 03:35:04 浏览:511
接收和发送服务器地址 发布:2025-05-18 03:33:48 浏览:372