Android开发中Context类的作⽤以及Context的详细⽤法
Android中Context的作⽤以及Context的详细⽤法
本⽂我们⼀起来探讨⼀下关于Android中Context的作⽤以及Context的详细⽤法,这对我们学习Android的资源访问有很⼤的帮助,⽂章中也贴出了⼀些关于Android Context使⽤的⽰例代码,⾮常不错,以下是原⽂:
Context基本概念
Context是什么?
1) Context是⼀个抽象类,其通⽤实现在ContextImpl类中。
2) Context:是⼀个访问application环境全局信息的接⼝,通过它可以访问application的资源和相关的类,其主要功能如下:
启动Activity
启动和停⽌Service
发送⼴播消息(Intent)
注册⼴播消息(Intent)接收者
可以访问APK中各种资源(如Resources和AssetManager等)
可以访问Package的相关信息
APK的各种权限管理
从以上分析可以看出,Context就是⼀个对APK包⽆所不知的⼤管家,⼤家需要什么,直接问它就可以了。
Context与View的关系
View与Context(或Activity)的关系类似于明星与经纪⼈的关系,所以创建View时,必须明确指定其Context(即经纪⼈或⼤管家),否则View就成不了明星。
Context家族关系
Context关键函数
1public abstract class Context {
2
3// 获取应⽤程序包的AssetManager实例
4public abstract AssetManager getAssets();
5
6// 获取应⽤程序包的Resources实例
7public abstract Resources getResources();
8
9// 获取PackageManager实例,以查看全局package信息
10public abstract PackageManager getPackageManager();
11
12// 获取应⽤程序包的ContentResolver实例
13public abstract ContentResolver getContentResolver();
14
15// 它返回当前进程的主线程的Looper,此线程分发调⽤给应⽤组件(activities, services等)
16public abstract Looper getMainLooper();
17
18// 返回当前进程的单实例全局Application对象的Context
19public abstract Context getApplicationContext();
20
21// 从string表中获取本地化的、格式化的字符序列
22public final CharSequence getText(int resId) {
23return getResources().getText(resId);
24 }
25
26// 从string表中获取本地化的字符串
27public final String getString(int resId) {
28return getResources().getString(resId);
29 }
30
31public final String getString(int resId, formatArgs) {
32return getResources().getString(resId, formatArgs);
33 }
34
35// 返回⼀个可⽤于获取包中类信息的class loader
36public abstract ClassLoader getClassLoader();
37
38// 返回应⽤程序包名
39public abstract String getPackageName();
40
41// 返回应⽤程序信息
42public abstract ApplicationInfo getApplicationInfo();
43
44// 根据⽂件名获取SharedPreferences
45public abstract SharedPreferences getSharedPreferences(String name,
46int mode);
47
48// 其根⽬录为: ExternalStorageDirectory()
49/*
50* @param type The type of files directory to return. May be null for
51* the root of the files directory or one of
52* the following Environment constants for a subdirectory:
53* {@link android.os.Environment#DIRECTORY_MUSIC},
54* {@link android.os.Environment#DIRECTORY_PODCASTS},
55* {@link android.os.Environment#DIRECTORY_RINGTONES},
56* {@link android.os.Environment#DIRECTORY_ALARMS},
57* {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
58* {@link android.os.Environment#DIRECTORY_PICTURES}, or
59* {@link android.os.Environment#DIRECTORY_MOVIES}.
60*/
61public abstract File getExternalFilesDir(String type);
62
63// 返回应⽤程序obb⽂件路径
64public abstract File getObbDir();
65
66// 启动⼀个新的activity
67public abstract void startActivity(Intent intent);
68
69// 启动⼀个新的activity
70public void startActivityAsUser(Intent intent, UserHandle user) {
71throw new RuntimeException("Not implemented. Must override in a subclass.");
72 }
73
74// 启动⼀个新的activity
75// intent: 将被启动的activity的描述信息
76// options: 描述activity将如何被启动
77public abstract void startActivity(Intent intent, Bundle options);
78
79// 启动多个新的activity
80public abstract void startActivities(Intent[] intents);
81
82// 启动多个新的activity
83public abstract void startActivities(Intent[] intents, Bundle options);
84
85// ⼴播⼀个intent给所有感兴趣的接收者,异步机制
86public abstract void sendBroadcast(Intent intent);
87
88// ⼴播⼀个intent给所有感兴趣的接收者,异步机制
89public abstract void sendBroadcast(Intent intent,String receiverPermission);
90
91public abstract void sendOrderedBroadcast(Intent intent,String receiverPermission); 92
93public abstract void sendOrderedBroadcast(Intent intent,
94 String receiverPermission, BroadcastReceiver resultReceiver,
95 Handler scheduler, int initialCode, String initialData,
96 Bundle initialExtras);
97
98public abstract void sendBroadcastAsUser(Intent intent, UserHandle user);
99
100public abstract void sendBroadcastAsUser(Intent intent, UserHandle user,
101 String receiverPermission);
102
103// 注册⼀个BroadcastReceiver,且它将在主activity线程中运⾏
104public abstract Intent registerReceiver(BroadcastReceiver receiver,
105 IntentFilter filter);
106
107public abstract Intent registerReceiver(BroadcastReceiver receiver,
108 IntentFilter filter, String broadcastPermission, Handler scheduler);
109
110public abstract void unregisterReceiver(BroadcastReceiver receiver);
111
112// 请求启动⼀个application service
113public abstract ComponentName startService(Intent service);
114
115// 请求停⽌⼀个application service
116public abstract boolean stopService(Intent service);
117
118// 连接⼀个应⽤服务,它定义了application和service间的依赖关系
119public abstract boolean bindService(Intent service, ServiceConnection conn, 120int flags);
121
122// 断开⼀个应⽤服务,当服务重新开始时,将不再接收到调⽤,
123// 且服务允许随时停⽌
124public abstract void unbindService(ServiceConnection conn);
125
126// 返回系统级service句柄
127/*
128* @see #WINDOW_SERVICE
129* @see android.view.WindowManager
130* @see #LAYOUT_INFLATER_SERVICE
131* @see android.view.LayoutInflater
132* @see #ACTIVITY_SERVICE
133* @see android.app.ActivityManager
134* @see #POWER_SERVICE
135* @see android.os.PowerManager
136* @see #ALARM_SERVICE
137* @see android.app.AlarmManager
138* @see #NOTIFICATION_SERVICE
139* @see android.app.NotificationManager
140* @see #KEYGUARD_SERVICE
141* @see android.app.KeyguardManager
142* @see #LOCATION_SERVICE
143* @see android.location.LocationManager
144* @see #SEARCH_SERVICE
145* @see android.app.SearchManager
146* @see #SENSOR_SERVICE
147* @see android.hardware.SensorManager
148* @see #STORAGE_SERVICE
149* @see android.os.storage.StorageManager
150* @see #VIBRATOR_SERVICE
151* @see android.os.Vibrator
152* @see #CONNECTIVITY_SERVICE
153* @see android.ConnectivityManager
154* @see #WIFI_SERVICE
155* @see android.wifi.WifiManager
156* @see #AUDIO_SERVICE
157* @dia.AudioManager
158* @see #MEDIA_ROUTER_SERVICE
159* @dia.MediaRouter
160* @see #TELEPHONY_SERVICE
161* @lephony.TelephonyManager
162* @see #INPUT_METHOD_SERVICE
163* @see android.view.inputmethod.InputMethodManager
164* @see #UI_MODE_SERVICE
165* @see android.app.UiModeManager
166* @see #DOWNLOAD_SERVICE
167* @see android.app.DownloadManager
168*/
169public abstract Object getSystemService(String name);
170安卓intent用法
171public abstract int checkPermission(String permission, int pid, int uid);
172
173// 返回⼀个新的与application name对应的Context对象
174public abstract Context createPackageContext(String packageName,
175int flags) throws PackageManager.NameNotFoundException;
176
177// 返回基于当前Context对象的新对象,其资源与display相匹配
178public abstract Context createDisplayContext(Display display);
179 }
ContextImpl关键成员和函数
1/**
2* Common implementation of Context API, which provides the base
3* context object for Activity and other application components.
4*/
5class ContextImpl extends Context {
6private final static String TAG = "ContextImpl";
7private final static boolean DEBUG = false;
8
9private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs = 10new HashMap<String, SharedPreferencesImpl>();
11
12/*package*/ LoadedApk mPackageInfo; // 关键数据成员
13private String mBasePackageName;
14private Resources mResources;
15/*package*/ ActivityThread mMainThread; // 主线程
16
17 @Override
18public AssetManager getAssets() {
19return getResources().getAssets();
20 }
21
22 @Override
23public Looper getMainLooper() {
Looper();
25 }
26
27 @Override
28public Object getSystemService(String name) {
29 ServiceFetcher fetcher = SYSTEM_(name);
30return fetcher == null ? null : Service(this);
31 }
32
33 @Override
34public void startActivity(Intent intent, Bundle options) {
35 warnIfCallingFromSystemProcess();
36if ((Flags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
37throw new AndroidRuntimeException(
38 "Calling startActivity() from outside of an Activity "
39 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
40 + " Is this really what you want?");
41 }
Instrumentation().execStartActivity(
43 getOuterContext(), ApplicationThread(), null,
44 (Activity)null, intent, -1, options);
45 }
46 }
ContextWrapper
它只是对Context类的⼀种封装,它的构造函数包含了⼀个真正的Context引⽤,即ContextImpl对象。 1/**
2* Proxying implementation of Context that simply delegates all of its calls to
3* another Context. Can be subclassed to modify behavior without changing
4* the original Context.
5*/
6public class ContextWrapper extends Context {
7 Context mBase; //该属性指向⼀个ContextIml实例
8
9public ContextWrapper(Context base) {
10 mBase = base;
11 }
12
13/**
14* Set the base context for this ContextWrapper. All calls will then be
15* delegated to the base context. Throws
16* IllegalStateException if a base context has already been set.
17*
18* @param base The new base context for this wrapper.
19* 创建Application、Service、Activity,会调⽤该⽅法给mBase属性赋值
20*/
21protected void attachBaseContext(Context base) {
22if (mBase != null) {
23throw new IllegalStateException("Base context already set");
24 }
25 mBase = base;
26 }
27
28 @Override
29public Looper getMainLooper() {
MainLooper();
31 }
32
33 @Override
34public Object getSystemService(String name) {
SystemService(name);
36 }
37
38 @Override
39public void startActivity(Intent intent) {
40 mBase.startActivity(intent);
41 }
42 }
ContextThemeWrapper
该类内部包含了主题(Theme)相关的接⼝,即android:theme属性指定的。只有Activity需要主题,Service不需要主题,所以Service直接继承于ContextWrapper类。
1/**
2* A ContextWrapper that allows you to modify the theme from what is in the
3* wrapped context.
4*/
5public class ContextThemeWrapper extends ContextWrapper {
6private Context mBase;
7private int mThemeResource;
8private Resources.Theme mTheme;
9private LayoutInflater mInflater;
10private Configuration mOverrideConfiguration;
11private Resources mResources;
12
13public ContextThemeWrapper() {
14super(null);
15 }
16
17public ContextThemeWrapper(Context base, int themeres) {
18super(base);
19 mBase = base;
20 mThemeResource = themeres;
21 }
22
23 @Override protected void attachBaseContext(Context newBase) {
24super.attachBaseContext(newBase);
25 mBase = newBase;
26 }
27
28 @Override public void setTheme(int resid) {
29 mThemeResource = resid;
30 initializeTheme();
31 }
32
33 @Override public Resources.Theme getTheme() {
34if (mTheme != null) {
35return mTheme;
36 }
37
38 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
39 getApplicationInfo().targetSdkVersion);
40 initializeTheme();
41
42return mTheme;
43 }
44 }
何时创建Context
应⽤程序在以下⼏种情况下创建Context实例:
1) 创建Application 对象时,⽽且整个App共⼀个Application对象
2) 创建Service对象时
3) 创建Activity对象时
因此应⽤程序App共有的Context数⽬公式为:
总Context实例个数 = Service个数 + Activity个数 + 1(Application对应的Context实例)
ActivityThread消息处理函数与本节相关的内容如下:
1public void handleMessage(Message msg) {
2if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
3switch (msg.what) {
4case LAUNCH_ACTIVITY: { // 创建Activity对象
aceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
6 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
7
8 r.packageInfo = getPackageInfoNoCheck(
9 r.activityInfo.applicationInfo, rpatInfo);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论