一、Context类的使用场景

①、创建Application对象时,而且整个app公用一个Application对象

②、创建Service对象时

③、创建Activity对象时

二、应用程序共有几个Context的公式

①、  Context(总)=Context(service个数)+Context(activity个数)+1(一个application对象)

三、Context概念

①、Context是一个抽象类,其通用实现在ContextImpl类中。

②、Context是维持Android程序中各组件能过正常工作的一个核心功能类,开发中称:上下文

③、Context:是一个访问application(应用程序)环境全局信息的接口,通过它可以访问application的资源和相关的类,其主要功能如下:

1)、启动Activity
    2)、启动和停止Service
    3)、发送广播消息(Intent)
    4)、注册广播消息(Intent)接收者
    5)、可以访问APK中各种资源(如Resources和AssetManager等)
    6)、可以访问Package的相关信息
    7)、APK的各种权限管理

四、Context的继承

①、ContextIML(mPackageInfo)和ContextWrapper(mBase : Context)都继承自Context

②、Context API的通用实现,他为Activity和其他application组件提供基本的context对象

③、Context代理实现,他简单地把调用请求发送给另一个context

④、service、contextThemeWrapper、application皆继承自contextWrapper,activity继承自contextThemeWrapper

五、关键函数

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);
}

六、ContextIML关键成员以及函数

 /**
 * Common implementation of Context API, which provides the base
 * context object for Activity and other application components.
 */
 class ContextImpl extends Context {
 private final static String TAG = "ContextImpl";
 private final static boolean DEBUG = false;

 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
 new HashMap<String, SharedPreferencesImpl>();

 /*package*/ LoadedApk mPackageInfo; // 关键数据成员
 private String mBasePackageName;
 private Resources mResources;
 /*package*/ ActivityThread mMainThread; // 主线程

 @Override
 public AssetManager getAssets() {
 return getResources().getAssets();
 }

 @Override
 public Looper getMainLooper() {
 return mMainThread.getLooper();
 }

 @Override
 public Object getSystemService(String name) {
 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
 return fetcher == null ? null : fetcher.getService(this);
 }

 @Override
 public void startActivity(Intent intent, Bundle options) {
 warnIfCallingFromSystemProcess();
 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
 throw new AndroidRuntimeException(
 "Calling startActivity() from outside of an Activity "
 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
 + " Is this really what you want?");
 }
 mMainThread.getInstrumentation().execStartActivity(
 getOuterContext(), mMainThread.getApplicationThread(), null,
 (Activity)null, intent, -1, options);
 }
 }

七、ContextWrapper

它只是对Context类的一种封装,它的构造函数包含了一个真正的Context引用,即ContextImpl对象

 /**
 * Proxying implementation of Context that simply delegates all of its calls to
 * another Context.  Can be subclassed to modify behavior without changing
 * the original Context.
 */
 public class ContextWrapper extends Context {
 Context mBase; //该属性指向一个ContextIml实例

 public ContextWrapper(Context base) {
 mBase = base;
 }

 /**
 * Set the base context for this ContextWrapper.  All calls will then be
 * delegated to the base context.  Throws
 * IllegalStateException if a base context has already been set.
 *
 * @param base The new base context for this wrapper.
 * 创建Application、Service、Activity,会调用该方法给mBase属性赋值
 */
 protected void attachBaseContext(Context base) {
 if (mBase != null) {
 throw new IllegalStateException("Base context already set");
 }
 mBase = base;
 }

 @Override
 public Looper getMainLooper() {
 return mBase.getMainLooper();
 }

 @Override
 public Object getSystemService(String name) {
 return mBase.getSystemService(name);
 }

 @Override
 public void startActivity(Intent intent) {
 mBase.startActivity(intent);
 }
 }

八、ContextThemeWrapper

该类内部包含了主题(Theme)相关的接口,即android:theme属性指定的。只有Activity需要主题,Service不需要主题,所以Service直接继承于ContextWrapper类

 /**
 * A ContextWrapper that allows you to modify the theme from what is in the
 * wrapped context.
 */
 public class ContextThemeWrapper extends ContextWrapper {
 private Context mBase;
 private int mThemeResource;
 private Resources.Theme mTheme;
 private LayoutInflater mInflater;
 private Configuration mOverrideConfiguration;
 private Resources mResources;

 public ContextThemeWrapper() {
 super(null);
 }

 public ContextThemeWrapper(Context base, int themeres) {
 super(base);
 mBase = base;
 mThemeResource = themeres;
 }

 @Override protected void attachBaseContext(Context newBase) {
 super.attachBaseContext(newBase);
 mBase = newBase;
 }

 @Override public void setTheme(int resid) {
 mThemeResource = resid;
 initializeTheme();
 }

 @Override public Resources.Theme getTheme() {
 if (mTheme != null) {
 return mTheme;
 }

 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
 getApplicationInfo().targetSdkVersion);
 initializeTheme();

 return mTheme;
 }
 }

九、ActivityThread消息处理函数与本节相关内容如下

 public void handleMessage(Message msg) {
 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
 switch (msg.what) {
 case LAUNCH_ACTIVITY: { // 创建Activity对象
 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
 ActivityClientRecord r = (ActivityClientRecord)msg.obj;

 r.packageInfo = getPackageInfoNoCheck(
 r.activityInfo.applicationInfo, r.compatInfo);
 handleLaunchActivity(r, null);
 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 } break;

 case BIND_APPLICATION: // 创建Application对象
 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
 AppBindData data = (AppBindData)msg.obj;
 handleBindApplication(data);
 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 break;

 case CREATE_SERVICE: // 创建Service对象
 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
 handleCreateService((CreateServiceData)msg.obj);
 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 break;

 case BIND_SERVICE:  // Bind Service对象
 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
 handleBindService((BindServiceData)msg.obj);
 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 break;
 }
 }十、创建Application对象时创建Context实例
// ActivityThread.java
private void handleBindApplication(AppBindData data) {
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}

// LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}

Application app = null;

String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}

try {
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext = new ContextImpl(); // 创建ContextImpl实例
appContext.init(this, null, mActivityThread);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app); // 将Application实例传递给Context实例
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;

return app;
}
private Context createBaseContextForActivity(ActivityClientRecord r,
final Activity activity) {
ContextImpl appContext = new ContextImpl();  // 创建ContextImpl实例
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);

// For debugging purposes, if the activity's package name contains the value of
// the "debug.use-second-display" system property as a substring, then show
// its content on a secondary display if there is one.
Context baseContext = appContext;
String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty()
&& r.packageInfo.mPackageName.contains(pkgName)) {
DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
for (int displayId : dm.getDisplayIds()) {
if (displayId != Display.DEFAULT_DISPLAY) {
Display display = dm.getRealDisplay(displayId);
baseContext = appContext.createDisplayContext(display);
break;
}
}
}
return baseContext;
}

十一、创建Service对象时创建Context实例

通过startService或者bindService时,如果系统检测到需要新创建一个Service实例,就会回调handleCreateService()方法,完成相关数据操作。handleCreateService()函数位于 ActivityThread.java类,如下

 private void handleCreateService(CreateServiceData data) {
 // If we are getting ready to gc after going to the background, well
 // we are back active so skip it.
 unscheduleGcIdler();

 LoadedApk packageInfo = getPackageInfoNoCheck(
 data.info.applicationInfo, data.compatInfo);
 Service service = null;
 try {
 java.lang.ClassLoader cl = packageInfo.getClassLoader();
 service = (Service) cl.loadClass(data.info.name).newInstance();
 } catch (Exception e) {
 if (!mInstrumentation.onException(service, e)) {
 throw new RuntimeException(
 "Unable to instantiate service " + data.info.name
 + ": " + e.toString(), e);
 }
 }

 try {
 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

 ContextImpl context = new ContextImpl(); // 创建ContextImpl实例
 context.init(packageInfo, null, this);

 Application app = packageInfo.makeApplication(false, mInstrumentation);
 context.setOuterContext(service);
 service.attach(context, this, data.info.name, data.token, app,
 ActivityManagerNative.getDefault());
 service.onCreate();
 mServices.put(data.token, service);
 try {
 ActivityManagerNative.getDefault().serviceDoneExecuting(
 data.token, 0, 0, 0);
 } catch (RemoteException e) {
 // nothing to do.
 }
 } catch (Exception e) {
 if (!mInstrumentation.onException(service, e)) {
 throw new RuntimeException(
 "Unable to create service " + data.info.name
 + ": " + e.toString(), e);
 }
 }
 }
 private void handleCreateService(CreateServiceData data) {
 // If we are getting ready to gc after going to the background, well
 // we are back active so skip it.
 unscheduleGcIdler();

 LoadedApk packageInfo = getPackageInfoNoCheck(
 data.info.applicationInfo, data.compatInfo);
 Service service = null;
 try {
 java.lang.ClassLoader cl = packageInfo.getClassLoader();
 service = (Service) cl.loadClass(data.info.name).newInstance();
 } catch (Exception e) {
 if (!mInstrumentation.onException(service, e)) {
 throw new RuntimeException(
 "Unable to instantiate service " + data.info.name
 + ": " + e.toString(), e);
 }
 }

 try {
 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

 ContextImpl context = new ContextImpl(); // 创建ContextImpl实例
 context.init(packageInfo, null, this);

 Application app = packageInfo.makeApplication(false, mInstrumentation);
 context.setOuterContext(service);
 service.attach(context, this, data.info.name, data.token, app,
 ActivityManagerNative.getDefault());
 service.onCreate();
 mServices.put(data.token, service);
 try {
 ActivityManagerNative.getDefault().serviceDoneExecuting(
 data.token, 0, 0, 0);
 } catch (RemoteException e) {
 // nothing to do.
 }
 } catch (Exception e) {
 if (!mInstrumentation.onException(service, e)) {
 throw new RuntimeException(
 "Unable to create service " + data.info.name
 + ": " + e.toString(), e);
 }
 }
 }

Android Context类的更多相关文章

  1. Android开发中Context类的作用以及Context的详细用法

    Android中Context的作用以及Context的详细用法 本文我们一起来探讨一下关于Android中Context的作用以及Context的详细用法,这对我们学习Android的资源访问有很大 ...

  2. Android开发——Context类的各种细节问题

    0. 前言   Context相信所有的Android开发人员基本上每天都在接触,因为它太常见了.但实际上Context有太多小的细节并不被大家所关注,那么今天我们就来学习一下那些你所不知道的细节. ...

  3. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

  4. Android Context 是什么?

    andorid 开发(42)  版权声明:本文为博主原创文章,未经博主允许不得转载. [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] PS ...

  5. Android Context创建过程

        特定的资源或者类构成了Android应用程序的运行上下文环境 PackageManager, ClassLoader, Assert等等 Android应用程序窗口的运行上下文环境是通过Con ...

  6. 源码心德`Context`类

    Context,中文直译为“上下文”,SDK中对其说明如下: Interface to global information about an application environment. Thi ...

  7. Android 服务类Service 的具体学习

    上一篇说到了通知栏Notification,提起通知栏,不得让人想到Service以及BroadcastReceive,作为android的4大组建的2个重要成员,我们没少和它们打交道.它们能够在无形 ...

  8. Android Context讲解(转)

    博客出处 前言:本文是我读<Android内核剖析>第7章 后形成的读书笔记 ,在此向欲了解Android框架的书籍推荐此书. 大家好, 今天给大家介绍下我们在应用开发中最熟悉而陌生的朋友 ...

  9. 【42】android Context深度剖析

    android程序和java程序的区别 Android程序不像Java程序一样,随便创建一个类,写个main()方法就能跑了,而是要有一个完整的Android工程环境,在这个环境下,我们有像Activ ...

随机推荐

  1. 11-部署Heapster插件

    配置和安装 Heapster 到 heapster release 页面 下载最新版本的 heapster. $ wget https://github.com/kubernetes/heapster ...

  2. 自动化测试 selenium 环境搭建

    做 web 项目,测试是无法避免的.对于某些特定功能,采用单元测试就行.但如果想对网站进行整体测试,人工点击测试可行但有点累,如果能借助自动化测试工具就更好了.selenium 就是一款能满足这样要求 ...

  3. [EXP]Microsoft Windows 10 - XmlDocument Insecure Sharing Privilege Escalation

    Windows: XmlDocument Insecure Sharing Elevation of Privilege Platform: Windows (almost certainly ear ...

  4. [源码]Delphi源码免杀之函数动态调用 实现免杀的下载者

    [免杀]Delphi源码免杀之函数动态调用 实现免杀的下载者 2013-12-30 23:44:21         来源:K8拉登哥哥's Blog   自己编译这份代码看看 过N多杀软  没什么技 ...

  5. List和ArrayList的区别

    List是一个接口,而ListArray是一个类. ListArray继承并实现了List. 所以List不能被构造,但可以向上面那样为List创建一个引用,而ListArray就可以被构造. Lis ...

  6. Ubuntu下安装程序的三种方法(转)

    引言 在Ubuntu当中,安装应用程序我所知道的有三种方法,分别是apt-get,dpkg安装deb和make install安装源码包三种.下面针对每一种方法各举例来说明. 一.apt-get方法 ...

  7. Redis学习系列七分布式锁

    一.简介 熟悉.Net多线程的都知道,当多个线程同时操作一个全局缓存对象(static对象实例.Dictionary.List等)时,会存在多线程争用问题,包括EF.Dapper等本身的缓存机制,都存 ...

  8. .net core build docker image

    1.创建.net core web项目 2.添加Dockerfile文件 # 基于microsoft/dotnet:2.1-aspnetcore-runtime构建Docker Image FROM ...

  9. 安装scrapy框架出错的解决

    要安装scrapy 一般会出现 以下错误(要先安装twisted) 今天通过pip安装twisted遇到了“error: Microsoft Visual C++ 14.0 is required”错 ...

  10. java ee期末项目相关

    1.项目简介 本项目是对纸杯生产进行管理的的一个系统,从前端接收到订单,然后根据订单内容进行纸杯的生产.如下为该系统的总流程图: 1.项目系统架构图 3.系统用例图 4.ER图 主要的代码和相关文件见 ...