您的位置:首页 > 移动开发 > Android开发

Context详解(一)

2015-10-23 21:03 609 查看
Context概述

一个Context提供对应用状态信息的访问。Context提供活动(Activities),碎片(Fragments)还有服务(Services)等对于资源文件(resource files),图像文件(images),主题(themes/styles)和外部存储目录的访问方式。Context同时提供对Android内置服务,比如布局填充(layout inflation),键盘(keyboard),寻找内容提供器(content providers)等的访问。

在很多情况下当我们需要用到context的时候,因为activity继承(inherit)context类的缘故,我们只需要传递当前的activity的实例就行了

例如

Intent intent = new Intent(this,SecondActivity.class);

在很多情况下我们在由activity创建的内部对象,比如适配器(adapters)和碎片,我们需要传递当前activity实例给这些内部类。另外,当我们不在一个活动中时(这时我们在一个应用(application)或者服务中),我们可以使用application context代替。

Context有什么用?

以下是一些关于Context对象的应用

显式启动组件

// Provide context if MyActivity is an internal activity.

Intent intent = new Intent(context, MyActivity.class);

startActivity(intent);

当显式启动一个组件时,需要两个信息:

包名,指定包含模块的应用名称

完全指定的java类名

如果启动一个内部组件,通过context.getPackegeName()方法提取当前应用的包名,context也可以传递

创建一个视图(view)

TextView textView = new TextView(context);

context包含以下视图所需要的信息:

设备屏幕尺寸和大小信息,为了转换dp(设备独立像素),sp(放大像素)为普通像素

设计样式属性

为onClick回调方法提供的对于活动的引用

找出XML布局文件中的布局

我们使用context得到LayoutInflater并将XML文件布局写入到内存中

// A context is required when creating views.

LayoutInflater inflater = LayoutInflater.from(context);

inflater.inflate(R.layout.my_layout, parent);

发送本地广播

当我们发送或者注册一个本地广播接收器时使用context来得到本地广播管理者(LocalBroadcastManager):

// The context contains a reference to the main Looper,

// which manages the queue for the application’s main thread.

Intent broadcastIntent = new Intent(“custom-action”);

LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

检索系统服务

为了从一个应用发送通告(notification),需要通告管理器(NotificationManager)系统服务:

// Context objects are able to fetch or start system services.

NotificationManager manager =

(NotificationManager) getSystemService(NOTIFICATION_SERVICE);

int notificationId = 1;

// Context is required to construct RemoteViews

Notification.Builder builder =

new Notification.Builder(context).setContentTitle(“custom title”);

notificationManager.notify(notificationId, builder.build());

应用 VS 活动context

主题(themes)和样式(styles)通常在应用层次应用,但是同时它们也可以在活动层级上指定。用这种方式,多个活动可以拥有一系列不同的主题集和样式集(例如,在一个活动中我们不需要ActionBar)。你可能会注意到,在AndroidManifest.xml中在应用层级一般都有一个android:theme。我们可以在活动层级指定一个不同的android:theme,此主题会覆盖应用层级的主题:

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/MyCustomTheme">


因此,知道有应用context和活动context的分别很是重要。大多数视图需要传入一个活动context来知道应该使用什么主题,样式,尺寸。如果没有为活动显式指定主题,就默认使用为应用指定的全局主题。

在大多数情况下,你应该使用活动context。正常情况下,在java中,this代表当前类的实例,其可以被

应用在任何需要context的内部方法中。下面的例子体现了Toast如何使用这个方法执行:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "hello", Toast.LENGTH_SHORT).show();
}


}

匿名方法

当使用匿名方法实现监听器的时候,this代表的是最里层的类的实例,也就是监听器的实例,这时直接使用this就不恰当了。在这种情况下,外部类必须要显式指定,例如MainActivity.this,以得到正确活动的实例:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

TextView tvTest = (TextView) findViewById(R.id.abc);
tvTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_SHORT).show();
}
});
}
}


适配器

数组适配器

当我们为一个ListView创建一个适配器的时候,方法getContext()通常被调用在布局获取(layout inflation)阶段。这个方法使用初始化数组适配器(ArrayAdapter)的context:

if (convertView == null) {

convertView =

LayoutInflater

.from(getContext())

.inflate(R.layout.item_user, parent, false);

}

如果你用应用context初始化数组适配器,继而你可能会发现主题和样式并没有被应用。这个时候,确认你传递了活动context。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 应用 布局