Android Context进阶
一、介绍
Context是一个抽象类,它的主要实现在其它派生类ContextImpl类中。它是访问Application全局信息的接口,通过它可以访问Application的所有资源和相关类。其主要功能如下:
- 启动Activity。
- 启动或停止Service。
- 发送广播消息(Intent)。
- 注册广播消息(Intent)接收器。
- 访问APK包中各种资源(Resources或AssetManager)。
- 访问Package的相关信息。
- 访问APK包的各种权限管理。
PS:Context的角色相当于APK包的管家,关于应用的所有消息、事情、信息都可以从Context中得到。
二、Context与View的关系
由于Context存储有Application的全局信息,在创建View的时候,要将其传递给View,从而让View能够得到想要的信息数据。比如,在创建控件时
PS:View与Context(或Activity)的关系相当于,主人和管家的关系。管家知道主人家的一切事情。
Context类主要方法:
1 public abstract class Context { 2 3 // 获取应用程序包的AssetManager实例 4 public abstract AssetManager getAssets(); 5 6 // 获取应用程序包的Resources实例 7 public abstract Resources getResources(); 8 9 // 获取PackageManager实例,以查看全局package信息 10 public abstract PackageManager getPackageManager(); 11 12 // 获取应用程序包的ContentResolver实例 13 public abstract ContentResolver getContentResolver(); 14 15 // 它返回当前进程的主线程的Looper,此线程分发调用给应用组件(activities, services等) 16 public abstract Looper getMainLooper(); 17 18 // 返回当前进程的单实例全局Application对象的Context 19 public abstract Context getApplicationContext(); 20 21 // 从string表中获取本地化的、格式化的字符序列 22 public final CharSequence getText(int resId) { 23 return getResources().getText(resId); 24 } 25 26 // 从string表中获取本地化的字符串 27 public final String getString(int resId) { 28 return getResources().getString(resId); 29 } 30 31 public final String getString(int resId, Object... formatArgs) { 32 return getResources().getString(resId, formatArgs); 33 } 34 35 // 返回一个可用于获取包中类信息的class loader 36 public abstract ClassLoader getClassLoader(); 37 38 // 返回应用程序包名 39 public abstract String getPackageName(); 40 41 // 返回应用程序信息 42 public abstract ApplicationInfo getApplicationInfo(); 43 44 // 根据文件名获取SharedPreferences 45 public abstract SharedPreferences getSharedPreferences(String name, 46 int mode); 47 48 // 其根目录为: Environment.getExternalStorageDirectory() 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 */ 61 public abstract File getExternalFilesDir(String type); 62 63 // 返回应用程序obb文件路径 64 public abstract File getObbDir(); 65 66 // 启动一个新的activity 67 public abstract void startActivity(Intent intent); 68 69 // 启动一个新的activity 70 public void startActivityAsUser(Intent intent, UserHandle user) { 71 throw new RuntimeException("Not implemented. Must override in a subclass."); 72 } 73 74 // 启动一个新的activity 75 // intent: 将被启动的activity的描述信息 76 // options: 描述activity将如何被启动 77 public abstract void startActivity(Intent intent, Bundle options); 78 79 // 启动多个新的activity 80 public abstract void startActivities(Intent[] intents); 81 82 // 启动多个新的activity 83 public abstract void startActivities(Intent[] intents, Bundle options); 84 85 // 广播一个intent给所有感兴趣的接收者,异步机制 86 public abstract void sendBroadcast(Intent intent); 87 88 // 广播一个intent给所有感兴趣的接收者,异步机制 89 public abstract void sendBroadcast(Intent intent,String receiverPermission); 90 91 public abstract void sendOrderedBroadcast(Intent intent,String receiverPermission); 92 93 public abstract void sendOrderedBroadcast(Intent intent, 94 String receiverPermission, BroadcastReceiver resultReceiver, 95 Handler scheduler, int initialCode, String initialData, 96 Bundle initialExtras); 97 98 public abstract void sendBroadcastAsUser(Intent intent, UserHandle user); 99 100 public abstract void sendBroadcastAsUser(Intent intent, UserHandle user, 101 String receiverPermission); 102 103 // 注册一个BroadcastReceiver,且它将在主activity线程中运行 104 public abstract Intent registerReceiver(BroadcastReceiver receiver, 105 IntentFilter filter); 106 107 public abstract Intent registerReceiver(BroadcastReceiver receiver, 108 IntentFilter filter, String broadcastPermission, Handler scheduler); 109 110 public abstract void unregisterReceiver(BroadcastReceiver receiver); 111 112 // 请求启动一个application service 113 public abstract ComponentName startService(Intent service); 114 115 // 请求停止一个application service 116 public abstract boolean stopService(Intent service); 117 118 // 连接一个应用服务,它定义了application和service间的依赖关系 119 public abstract boolean bindService(Intent service, ServiceConnection conn, 120 int flags); 121 122 // 断开一个应用服务,当服务重新开始时,将不再接收到调用, 123 // 且服务允许随时停止 124 public abstract void unbindService(ServiceConnection conn); 125 126 127 // 返回系统级service句柄 128 /* 129 * @see #WINDOW_SERVICE 130 * @see android.view.WindowManager 131 * @see #LAYOUT_INFLATER_SERVICE 132 * @see android.view.LayoutInflater 133 * @see #ACTIVITY_SERVICE 134 * @see android.app.ActivityManager 135 * @see #POWER_SERVICE 136 * @see android.os.PowerManager 137 * @see #ALARM_SERVICE 138 * @see android.app.AlarmManager 139 * @see #NOTIFICATION_SERVICE 140 * @see android.app.NotificationManager 141 * @see #KEYGUARD_SERVICE 142 * @see android.app.KeyguardManager 143 * @see #LOCATION_SERVICE 144 * @see android.location.LocationManager 145 * @see #SEARCH_SERVICE 146 * @see android.app.SearchManager 147 * @see #SENSOR_SERVICE 148 * @see android.hardware.SensorManager 149 * @see #STORAGE_SERVICE 150 * @see android.os.storage.StorageManager 151 * @see #VIBRATOR_SERVICE 152 * @see android.os.Vibrator 153 * @see #CONNECTIVITY_SERVICE 154 * @see android.net.ConnectivityManager 155 * @see #WIFI_SERVICE 156 * @see android.net.wifi.WifiManager 157 * @see #AUDIO_SERVICE 158 * @see android.media.AudioManager 159 * @see #MEDIA_ROUTER_SERVICE 160 * @see android.media.MediaRouter 161 * @see #TELEPHONY_SERVICE 162 * @see android.telephony.TelephonyManager 163 * @see #INPUT_METHOD_SERVICE 164 * @see android.view.inputmethod.InputMethodManager 165 * @see #UI_MODE_SERVICE 166 * @see android.app.UiModeManager 167 * @see #DOWNLOAD_SERVICE 168 * @see android.app.DownloadManager 169 */ 170 public abstract Object getSystemService(String name); 171 172 public abstract int checkPermission(String permission, int pid, int uid); 173 174 // 返回一个新的与application name对应的Context对象 175 public abstract Context createPackageContext(String packageName, 176 int flags) throws PackageManager.NameNotFoundException; 177 178 // 返回基于当前Context对象的新对象,其资源与display相匹配 179 public abstract Context createDisplayContext(Display display); 180 }
三、Context创建时机
- 在创建Application对象时,而整个Application仅有一个Application对象。
- 在创建Service服务时。
- 在创建Activity时。
不难发现,创建Context的时机就是在创建Context的实现类的时候。当应用程序第一次启动时,Android系统都会创建一个Application对象,同时创建Application Context,所有的组件共同拥有这样一个Context对象,这个应用上下文对象贯穿整个应用进程的生命周期,为应用全局提供了功能和环境支持。而创建Activity和Service组件时,系统也会给它们提供运行的上下文环境,即创建Activity实例、Service实例的Context对象。所以一些开发者在Activity中获取Context对象时,可以直接使用this,而在匿名内部类中,就必须指定XXXXXActivity.this才可以获得该Activity的Context对象。当然,也可以使用getApplicatoinContext()方法来获取整个应用的Context对象,但是,通过getApplicationContext()方法获取的Context对象是整个应用的上下文的引用,这与某个组件的上下文引用,在某些时候还是有区别的。
PS:Context数量 = Applicaiton数量 + Service服务数量 + Activity数量。
四、Context作为构造函数参数作用
Context作为构造函数参数,可以帮助对象启动Activity,获取项目资源,查询应用的私有存储空间等任务。