Android Context简介
1. Context基本概念
1.1 Context是什么?
1) Context是一个抽象类,其通用实现在ContextImpl类中。
2) Context:是一个访问application环境全局信息的接口,通过它可以访问application的资源和相关的类,其主要功能如下:
• 启动Activity
• 启动和停止Service
• 发送广播消息(Intent)
• 注册广播消息(Intent)接收者
• 可以访问APK中各种资源(如Resources和AssetManager等)
• 可以访问Package的相关信息
• APK的各种权限管理
从以上分析可以看出,Context就是一个对APK包无所不知的大管家,大家需要什么,直接问它就可以了。
1.1.1 Context与View的关系
View与Context(或Activity)的关系类似于明星与经纪人的关系,所以创建View时,必须明确指定其Context(即经纪人或大管家),否则View就成不了明星。
1.2 Context家族关系
1.3 Context关键函数
- public abstract class Context {
- // 获取应用程序包的AssetManager实例
- public abstract AssetManager getAssets();
- // 获取应用程序包的Resources实例
- public abstract Resources getResources();
- // 获取PackageManager实例,以查看全局package信息
- public abstract PackageManager getPackageManager();
- // 获取应用程序包的ContentResolver实例
- public abstract ContentResolver getContentResolver();
- // 它返回当前进程的主线程的Looper,此线程分发调用给应用组件(activities, services等)
- public abstract Looper getMainLooper();
- // 返回当前进程的单实例全局Application对象的Context
- public abstract Context getApplicationContext();
- // 从string表中获取本地化的、格式化的字符序列
- public final CharSequence getText(int resId) {
- return getResources().getText(resId);
- }
- // 从string表中获取本地化的字符串
- public final String getString(int resId) {
- return getResources().getString(resId);
- }
- public final String getString(int resId, Object... formatArgs) {
- return getResources().getString(resId, formatArgs);
- }
- // 返回一个可用于获取包中类信息的class loader
- public abstract ClassLoader getClassLoader();
- // 返回应用程序包名
- public abstract String getPackageName();
- // 返回应用程序信息
- public abstract ApplicationInfo getApplicationInfo();
- // 根据文件名获取SharedPreferences
- public abstract SharedPreferences getSharedPreferences(String name,
- int mode);
- // 其根目录为: Environment.getExternalStorageDirectory()
- /*
- * @param type The type of files directory to return. May be null for
- * the root of the files directory or one of
- * the following Environment constants for a subdirectory:
- * {@link android.os.Environment#DIRECTORY_MUSIC},
- * {@link android.os.Environment#DIRECTORY_PODCASTS},
- * {@link android.os.Environment#DIRECTORY_RINGTONES},
- * {@link android.os.Environment#DIRECTORY_ALARMS},
- * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
- * {@link android.os.Environment#DIRECTORY_PICTURES}, or
- * {@link android.os.Environment#DIRECTORY_MOVIES}.
- */
- public abstract File getExternalFilesDir(String type);
- // 返回应用程序obb文件路径
- public abstract File getObbDir();
- // 启动一个新的activity
- public abstract void startActivity(Intent intent);
- // 启动一个新的activity
- public void startActivityAsUser(Intent intent, UserHandle user) {
- throw new RuntimeException("Not implemented. Must override in a subclass.");
- }
- // 启动一个新的activity
- // intent: 将被启动的activity的描述信息
- // options: 描述activity将如何被启动
- public abstract void startActivity(Intent intent, Bundle options);
- // 启动多个新的activity
- public abstract void startActivities(Intent[] intents);
- // 启动多个新的activity
- public abstract void startActivities(Intent[] intents, Bundle options);
- // 广播一个intent给所有感兴趣的接收者,异步机制
- public abstract void sendBroadcast(Intent intent);
- // 广播一个intent给所有感兴趣的接收者,异步机制
- public abstract void sendBroadcast(Intent intent,String receiverPermission);
- public abstract void sendOrderedBroadcast(Intent intent,String receiverPermission);
- public abstract void sendOrderedBroadcast(Intent intent,
- String receiverPermission, BroadcastReceiver resultReceiver,
- Handler scheduler, int initialCode, String initialData,
- Bundle initialExtras);
- public abstract void sendBroadcastAsUser(Intent intent, UserHandle user);
- public abstract void sendBroadcastAsUser(Intent intent, UserHandle user,
- String receiverPermission);
- // 注册一个BroadcastReceiver,且它将在主activity线程中运行
- public abstract Intent registerReceiver(BroadcastReceiver receiver,
- IntentFilter filter);
- public abstract Intent registerReceiver(BroadcastReceiver receiver,
- IntentFilter filter, String broadcastPermission, Handler scheduler);
- public abstract void unregisterReceiver(BroadcastReceiver receiver);
- // 请求启动一个application service
- public abstract ComponentName startService(Intent service);
- // 请求停止一个application service
- public abstract boolean stopService(Intent service);
- // 连接一个应用服务,它定义了application和service间的依赖关系
- public abstract boolean bindService(Intent service, ServiceConnection conn,
- int flags);
- // 断开一个应用服务,当服务重新开始时,将不再接收到调用,
- // 且服务允许随时停止
- public abstract void unbindService(ServiceConnection conn);
- // 返回系统级service句柄
- /*
- * @see #WINDOW_SERVICE
- * @see android.view.WindowManager
- * @see #LAYOUT_INFLATER_SERVICE
- * @see android.view.LayoutInflater
- * @see #ACTIVITY_SERVICE
- * @see android.app.ActivityManager
- * @see #POWER_SERVICE
- * @see android.os.PowerManager
- * @see #ALARM_SERVICE
- * @see android.app.AlarmManager
- * @see #NOTIFICATION_SERVICE
- * @see android.app.NotificationManager
- * @see #KEYGUARD_SERVICE
- * @see android.app.KeyguardManager
- * @see #LOCATION_SERVICE
- * @see android.location.LocationManager
- * @see #SEARCH_SERVICE
- * @see android.app.SearchManager
- * @see #SENSOR_SERVICE
- * @see android.hardware.SensorManager
- * @see #STORAGE_SERVICE
- * @see android.os.storage.StorageManager
- * @see #VIBRATOR_SERVICE
- * @see android.os.Vibrator
- * @see #CONNECTIVITY_SERVICE
- * @see android.net.ConnectivityManager
- * @see #WIFI_SERVICE
- * @see android.net.wifi.WifiManager
- * @see #AUDIO_SERVICE
- * @see android.media.AudioManager
- * @see #MEDIA_ROUTER_SERVICE
- * @see android.media.MediaRouter
- * @see #TELEPHONY_SERVICE
- * @see android.telephony.TelephonyManager
- * @see #INPUT_METHOD_SERVICE
- * @see android.view.inputmethod.InputMethodManager
- * @see #UI_MODE_SERVICE
- * @see android.app.UiModeManager
- * @see #DOWNLOAD_SERVICE
- * @see android.app.DownloadManager
- */
- public abstract Object getSystemService(String name);
- public abstract int checkPermission(String permission, int pid, int uid);
- // 返回一个新的与application name对应的Context对象
- public abstract Context createPackageContext(String packageName,
- int flags) throws PackageManager.NameNotFoundException;
- // 返回基于当前Context对象的新对象,其资源与display相匹配
- public abstract Context createDisplayContext(Display display);
- }
1.4 ContextImpl关键成员和函数
1.5 ContextWrapper
它只是对Context类的一种封装,它的构造函数包含了一个真正的Context引用,即ContextImpl对象。
1.6 ContextThemeWrapper
该类内部包含了主题(Theme)相关的接口,即Android:theme属性指定的。只有Activity需要主题,Service不需要主题,所以Service直接继承于ContextWrapper类。
2. 何时创建Context
应用程序在以下几种情况下创建Context实例:
1) 创建Application 对象时, 而且整个App共一个Application对象
2) 创建Service对象时
3) 创建Activity对象时
因此应用程序App共有的Context数目公式为:
总Context实例个数 = Service个数 + Activity个数 + 1(Application对应的Context实例)
ActivityThread消息处理函数与本节相关的内容如下:
2.1 创建Application对象时创建Context实例
每个应用程序在第一次启动时,都会首先创建一个Application对象。从startActivity流程可知,创建Application的时机在handleBindApplication()方法中,该函数位于 ActivityThread.Java类中 ,相关代码如下:
2.2 创建Activity对象时创建Context实例
通过startActivity()或startActivityForResult()请求启动一个Activity时,如果系统检测需要新建一个Activity对象时,就会回调handleLaunchActivity()方法,该方法继而调用performLaunchActivity()方法,去创建一个Activity实例,并且回调onCreate(),onStart()方法等,函数都位于 ActivityThread.java类 ,相关代码如下:
2.3 创建Service对象时创建Context实例
通过startService或者bindService时,如果系统检测到需要新创建一个Service实例,就会回调handleCreateService()方法,完成相关数据操作。handleCreateService()函数位于 ActivityThread.java类,如下: