一、Context相关类的继承关系
- public
abstract class Context { -
... -
public abstract Object getSystemService(String name); //获得系统级服务 -
public abstract void startActivity(Intent intent); //通过一个Intent启动Activity -
public abstract ComponentName startService(Intent service); //启动Service -
//根据文件名得到SharedPreferences对象 -
public abstract SharedPreferences getSharedPreferences(String name,int mode); -
... - }
-
- class
ContextImpl extends Context{ -
//所有Application程序公用一个mPackageInfo对象 -
ActivityThread.PackageInfo mPackageInfo; -
-
@Override -
public Object getSystemService(String name){ -
... -
else if (ACTIVITY_SERVICE.equals(name)) { -
return getActivityManager(); -
} -
else if (INPUT_METHOD_SERVICE.equals(name)) { -
return InputMethodManager.getInstance(this); -
} -
} -
@Override -
public void startActivity(Intent intent) { -
... -
//开始启动一个Activity -
mMainThread.getInstrumentation().execStartActivity( -
getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1); -
} - }
- public
class ContextWrapper extends Context { -
Context mBase; //该属性指向一个ContextIml实例,一般在创建Application、Service、Activity时赋值 -
-
//创建Application、Service、Activity,会调用该方法给mBase属性赋值 -
protected void attachBaseContext(Context base) { -
if (mBase != null) { -
throw new IllegalStateException("Base context already set"); -
} -
mBase = base; -
} -
@Override -
public void startActivity(Intent intent) { -
mBase.startActivity(intent); //调用mBase实例方法 -
} - }
- public
class ContextThemeWrapper extends ContextWrapper { -
//该属性指向一个ContextIml实例,一般在创建Application、Service、Activity时赋值 -
-
private Context mBase; -
//mBase赋值方式同样有一下两种 -
public ContextThemeWrapper(Context base, int themeres) { -
super(base); -
mBase = base; -
mThemeResource = themeres; -
} -
-
@Override -
protected void attachBaseContext(Context newBase) { -
super.attachBaseContext(newBase); -
mBase = newBase; -
} - }
二、什么时候创建Context实例
清楚的话,创建Application的时机在创建handleBindApplication()方法中,该函数位于ActivityThread.java类中 ,如下:
- //创建Application时同时创建的ContextIml实例
- private
final void handleBindApplication(AppBindData data){ -
... -
///创建Application对象 -
Application app = data.info.makeApplication(data.restrictedBackupMode, null); -
... - }
-
- public
Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { -
... -
try { -
java.lang.ClassLoader cl = getClassLoader(); -
ContextImpl appContext = new ContextImpl(); //创建一个ContextImpl对象实例 -
appContext.init(this, null, mActivityThread); //初始化该ContextIml实例的相关属性 -
///新建一个Application对象 -
app = mActivityThread.mInstrumentation.newApplication( -
cl, appClass, appContext); -
appContext.setOuterContext(app); //将该Application实例传递给该ContextImpl实例 -
} -
... - }
- //创建一个Activity实例时同时创建ContextIml实例
- private
final void handleLaunchActivity(ActivityRecord r, Intent customIntent) { -
... -
Activity a = performLaunchActivity(r, customIntent); //启动一个Activity - }
- private
final Activity performLaunchActivity(ActivityRecord r, Intent customIntent) { -
... -
Activity activity = null; -
try { -
//创建一个Activity对象实例 -
java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); -
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); -
} -
if (activity != null) { -
ContextImpl appContext = new ContextImpl(); //创建一个Activity实例 -
appContext.init(r.packageInfo, r.token, this); //初始化该ContextIml实例的相关属性 -
appContext.setOuterContext(activity); //将该Activity信息传递给该ContextImpl实例 -
... -
} -
... - }
- //创建一个Service实例时同时创建ContextIml实例
- private
final void handleCreateService(CreateServiceData data){ -
... -
//创建一个Service实例 -
Service service = null; -
try { -
java.lang.ClassLoader cl = packageInfo.getClassLoader(); -
service = (Service) cl.loadClass(data.info.name).newInstance(); -
} catch (Exception e) { -
} -
... -
ContextImpl context = new ContextImpl(); //创建一个ContextImpl对象实例 -
context.init(packageInfo, null, this); //初始化该ContextIml实例的相关属性 -
//获得我们之前创建的Application对象信息 -
Application app = packageInfo.makeApplication(false, mInstrumentation); -
//将该Service信息传递给该ContextImpl实例 -
context.setOuterContext(service); -
... - }
型为PackageInfo)的相关方法而来。这说明ContextImp是一种轻量级类,而PackageInfo才是真正重量级的类。而一个App里的
所有ContextIml实例,都对应同一个packageInfo对象。
法就是通过调用getSharedPreferences()方法去根据相关信息获取SharedPreferences对象。具体流程如下:
- //Context类静态数据集合,以键值对保存了所有读取该xml文件后所形成的数据集合
- private
static final HashMap sSharedPrefs = -
new HashMap(); -
- @Override
- public
SharedPreferences getSharedPreferences(String name, int mode){ -
//其所对应的SharedPreferencesImpl对象 ,该对象已一个HashMap集合保存了我们对该文件序列化结果 -
SharedPreferencesImpl sp; -
File f = getSharedPrefsFile(name); //该包下是否存在对应的文件,不存在就新建一个 -
synchronized (sSharedPrefs) { //是否已经读取过该文件,是就直接返回该SharedPreferences对象 -
sp = sSharedPrefs.get(f); -
if (sp != null && !sp.hasFileChanged()) { -
//Log.i(TAG, "Returning existing prefs " + name + ": " + sp); -
return sp; -
} -
} -
//以下为序列化该xml文件,同时将数据写到map集合中 -
Map map = null; -
if (f.exists() && f.canRead()) { -
try { -
str = new FileInputStream(f); -
map = XmlUtils.readMapXml(str); -
str.close(); -
} -
... -
} -
-
synchronized (sSharedPrefs) { -
if (sp != null) { -
//Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map); -
sp.replace(map); //更新数据集合 -
} else { -
sp = sSharedPrefs.get(f); -
if (sp == null) { -
//新建一个SharedPreferencesImpl对象,并且设置其相关属性 -
sp = new SharedPreferencesImpl(f, mode, map); -
sSharedPrefs.put(f, sp); -
} -
} -
return sp; -
} - }
- //soga,这种形式我们在分析Context
ContextIml时接触过 - //SharedPreferences只是一种接口,其真正实现类是SharedPreferencesImpl类
- private
static final class SharedPreferencesImpl implements SharedPreferences{ -
private Map mMap; //保存了该文件序列化结果后的操作, 键值对形式 -
-
//通过key值获取对应的value值 -
public String getString(String key, String defValue) { -
synchronized (this) { -
String v = (String)mMap.get(key); -
return v != null ? v : defValue; -
} -
} -
... -
//获得该SharedPreferencesImpl对象对应的Edito类,对数据进行操作 -
public final class EditorImpl implements Editor { -
private final Map mModified = Maps.newHashMap(); //保存了对键值变化的集合 -
} - }