Framework层的资源总结
2014-04-17 19:24
399 查看
本文主要介绍系统资源的加载、读取、添加流程。
一、加载。
1、优先加载的系统资源。
在zygote进程初始化时,有部分系统资源被优先加载,当他们加载完,zygote进程才开始启动其它应用进程。
Zygote是系统启动初始化的进程,如何执行那?
public static void main(String argv[]) {
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
registerZygoteSocket();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
gc();
// If requested, start system server directly from Zygote
if (argv.length != 2) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
if (argv[1].equals("start-system-server")) {
startSystemServer();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
Log.i(TAG, "Accepting command socket connections");
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
相信大家看到了public static void main,是否是就看到了亲人了。
这个函数中有三个很重要的方法。1、preload();2、startSystemServer();3、runSelectLoopMode();,这也是此函数内部执行的三个阶段。
我们来看加载“优先系统资源”。
static void preload() {
preloadClasses();
preloadResources();
}预加载分两步,预加载class,预加载Resource。我们来看预加载Resource。
private static void preloadResources() {
final VMRuntime runtime = VMRuntime.getRuntime();
Debug.startAllocCounting();
try {
System.gc();
runtime.runFinalizationSync();
mResources = Resources.getSystem();
mResources.startPreloading();
if (PRELOAD_RESOURCES) {
Log.i(TAG, "Preloading resources...");
long startTime = SystemClock.uptimeMillis();
TypedArray ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_drawables);
int N = preloadDrawables(runtime, ar);
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
startTime = SystemClock.uptimeMillis();
ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_color_state_lists);
N = preloadColorStateLists(runtime, ar);
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
}
mResources.finishPreloading();
} catch (RuntimeException e) {
Log.w(TAG, "Failure preloading resources", e);
} finally {
Debug.stopAllocCounting();
}
}首先通过Resource.getSystem得到Resource对象。此函数我们可以在应用层中调用,但通过此方式得到的Resource对象,依据上篇博文可知,仅能访问framework层资源。
public static Resources getSystem() {
synchronized (mSync) {
Resources ret = mSystem;
if (ret == null) {
ret = new Resources();
mSystem = ret;
}
return ret;
}
}
getSystem方法内部调用一个private类型的mResource构造函数,在构造中首先得到AssetManager对象,这一步保证了Resource类中的sSystem对象,仅能访问framework层资源。
总结一下:zygote进程创建Resource对象和普通进程不同,前者使用静态函数getSystem后者使用带参数的Resource构造创建,参数包含了应用程序资源文件的路径信息。
2、有了Resource对象,接着调用mResources.startPreloading();。
public final void startPreloading() {
synchronized (mSync) {
if (mPreloaded) {
throw new IllegalStateException("Resources already preloaded");
}
mPreloaded = true;
mPreloading = true;
}
}在finishPreloading中置为false。
public final void finishPreloading() {
if (mPreloading) {
mPreloading = false;
flushLayoutCache();
}
}这一步为Resource对象中的成员变量赋值。mPreloaded以及mPreloading成员属性的存在保证了getDrawable以及getColor不同的流程。
3、执行加载过程。preloadDrawable以及preloadColorStateLists。
TypedArray ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_drawables);
int N = preloadDrawables(runtime, ar);和
ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_color_state_lists);
N = preloadColorStateLists(runtime, ar);这两个函数目的是加载定义在com.android.internal.R.array.preloaded_drawables以及com.android.internal.R.array.preloaded_color_state_llists两个xml文件中定义的资源。
4、加载过程,就是执行Resource对象的loadDrawable以及loadColorxx等。但是与普通加载不同的是,此处加载会根据2种两个变量mPreloaded的true或者false,执行不同的逻辑,最终将加载的资源存放在Resource对象的成员静态List中。
if (mPreloading) {
if (isColorDrawable) {
sPreloadedColorDrawables.put(key, cs);
} else {
sPreloadedDrawables.put(key, cs);
}
} else {
synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached drawable @ #" +
// Integer.toHexString(key.intValue())
// + " in " + this + ": " + cs);
if (isColorDrawable) {
mColorDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
} else {
mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
}
}
}
private static final LongSparseArray<Drawable.ConstantState> sPreloadedDrawables
= new LongSparseArray<Drawable.ConstantState>();
private static final SparseArray<ColorStateList> mPreloadedColorStateLists
= new SparseArray<ColorStateList>();
private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
= new LongSparseArray<Drawable.ConstantState>();static关键字保证了被应用程序进程创建的新的Resource对象保存了zygote进程预加载的资源。
二、framework层资源的添加。
framework包含了很多资源,预加载的只是其中一部分,非预加载的资源不会被记载道Resource缓冲静态列表中。这意味着,多个应用需要一个非预加载资源,则会在各自的进程中保存一个资源的缓冲。
系统资源,按照是否公开,分为私有资源和公开资源。私有资源是指仅能在framework内部访问的资源或者说手机厂商拥有源码编译环境的厂商或者团体才能使用。公开资源是指被编译到android SDK中的资源
公开资源R文件:android.R
私有资源R文件:com.android.internal.R。
公开资源是私有资源的一个子集,私有资源来源自res/values/public.xml中的定义。在此文件中定义的string等资源在各个sdk版本中都会保持值一致。
framework值定义规范:
0x0104f000
01代表framework资源
04代表string类型的资源
f000:代表资源编号。
一、加载。
1、优先加载的系统资源。
在zygote进程初始化时,有部分系统资源被优先加载,当他们加载完,zygote进程才开始启动其它应用进程。
Zygote是系统启动初始化的进程,如何执行那?
public static void main(String argv[]) {
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
registerZygoteSocket();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
gc();
// If requested, start system server directly from Zygote
if (argv.length != 2) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
if (argv[1].equals("start-system-server")) {
startSystemServer();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
Log.i(TAG, "Accepting command socket connections");
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
相信大家看到了public static void main,是否是就看到了亲人了。
这个函数中有三个很重要的方法。1、preload();2、startSystemServer();3、runSelectLoopMode();,这也是此函数内部执行的三个阶段。
我们来看加载“优先系统资源”。
static void preload() {
preloadClasses();
preloadResources();
}预加载分两步,预加载class,预加载Resource。我们来看预加载Resource。
private static void preloadResources() {
final VMRuntime runtime = VMRuntime.getRuntime();
Debug.startAllocCounting();
try {
System.gc();
runtime.runFinalizationSync();
mResources = Resources.getSystem();
mResources.startPreloading();
if (PRELOAD_RESOURCES) {
Log.i(TAG, "Preloading resources...");
long startTime = SystemClock.uptimeMillis();
TypedArray ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_drawables);
int N = preloadDrawables(runtime, ar);
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
startTime = SystemClock.uptimeMillis();
ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_color_state_lists);
N = preloadColorStateLists(runtime, ar);
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
}
mResources.finishPreloading();
} catch (RuntimeException e) {
Log.w(TAG, "Failure preloading resources", e);
} finally {
Debug.stopAllocCounting();
}
}首先通过Resource.getSystem得到Resource对象。此函数我们可以在应用层中调用,但通过此方式得到的Resource对象,依据上篇博文可知,仅能访问framework层资源。
public static Resources getSystem() {
synchronized (mSync) {
Resources ret = mSystem;
if (ret == null) {
ret = new Resources();
mSystem = ret;
}
return ret;
}
}
private Resources() { mAssets = AssetManager.getSystem(); // NOTE: Intentionally leaving this uninitialized (all values set // to zero), so that anyone who tries to do something that requires // metrics will get a very wrong value. mConfiguration.setToDefaults(); mMetrics.setToDefaults(); updateConfiguration(null, null); mAssets.ensureStringBlocks(); mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; }
getSystem方法内部调用一个private类型的mResource构造函数,在构造中首先得到AssetManager对象,这一步保证了Resource类中的sSystem对象,仅能访问framework层资源。
总结一下:zygote进程创建Resource对象和普通进程不同,前者使用静态函数getSystem后者使用带参数的Resource构造创建,参数包含了应用程序资源文件的路径信息。
2、有了Resource对象,接着调用mResources.startPreloading();。
public final void startPreloading() {
synchronized (mSync) {
if (mPreloaded) {
throw new IllegalStateException("Resources already preloaded");
}
mPreloaded = true;
mPreloading = true;
}
}在finishPreloading中置为false。
public final void finishPreloading() {
if (mPreloading) {
mPreloading = false;
flushLayoutCache();
}
}这一步为Resource对象中的成员变量赋值。mPreloaded以及mPreloading成员属性的存在保证了getDrawable以及getColor不同的流程。
3、执行加载过程。preloadDrawable以及preloadColorStateLists。
TypedArray ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_drawables);
int N = preloadDrawables(runtime, ar);和
ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_color_state_lists);
N = preloadColorStateLists(runtime, ar);这两个函数目的是加载定义在com.android.internal.R.array.preloaded_drawables以及com.android.internal.R.array.preloaded_color_state_llists两个xml文件中定义的资源。
4、加载过程,就是执行Resource对象的loadDrawable以及loadColorxx等。但是与普通加载不同的是,此处加载会根据2种两个变量mPreloaded的true或者false,执行不同的逻辑,最终将加载的资源存放在Resource对象的成员静态List中。
if (mPreloading) {
if (isColorDrawable) {
sPreloadedColorDrawables.put(key, cs);
} else {
sPreloadedDrawables.put(key, cs);
}
} else {
synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached drawable @ #" +
// Integer.toHexString(key.intValue())
// + " in " + this + ": " + cs);
if (isColorDrawable) {
mColorDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
} else {
mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
}
}
}
private static final LongSparseArray<Drawable.ConstantState> sPreloadedDrawables
= new LongSparseArray<Drawable.ConstantState>();
private static final SparseArray<ColorStateList> mPreloadedColorStateLists
= new SparseArray<ColorStateList>();
private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
= new LongSparseArray<Drawable.ConstantState>();static关键字保证了被应用程序进程创建的新的Resource对象保存了zygote进程预加载的资源。
二、framework层资源的添加。
framework包含了很多资源,预加载的只是其中一部分,非预加载的资源不会被记载道Resource缓冲静态列表中。这意味着,多个应用需要一个非预加载资源,则会在各自的进程中保存一个资源的缓冲。
系统资源,按照是否公开,分为私有资源和公开资源。私有资源是指仅能在framework内部访问的资源或者说手机厂商拥有源码编译环境的厂商或者团体才能使用。公开资源是指被编译到android SDK中的资源
公开资源R文件:android.R
私有资源R文件:com.android.internal.R。
公开资源是私有资源的一个子集,私有资源来源自res/values/public.xml中的定义。在此文件中定义的string等资源在各个sdk版本中都会保持值一致。
framework值定义规范:
0x0104f000
01代表framework资源
04代表string类型的资源
f000:代表资源编号。
相关文章推荐
- 网络资源-黑马程序员Java 知识——精华总结
- 为java程序员整理的面试、编码、技巧、资源总结
- Android UI适配总结(一)寻找最佳匹配资源
- 京东前端工程化和静态资源管理全面总结
- 电信资源管理系统性能测试总结
- Android应用资源总结四:colorAccent,colorPrimary,colorPrimaryDark等的意义
- Java或者JAR包获取读取资源文件的路径的问题总结
- Framework层添加一个公共资源apk,可供应用调用
- GitHub安卓热门开源资源在项目中的使用及项目总结
- c# winform编程之多线程ui界面资源修改总结篇
- Android应用资源总结七:layer-list使用详解
- 【转】Unity 相关经典博客资源总结(持续更新)
- 京东前端工程化和静态资源管理全面总结
- spring的4个获取资源总结
- 揭开Eclipse的面纱 (关于Ecliplse所以资源及使用指导,很好的总结)
- 转载:[Share]2008年国外最佳Web设计/开发技巧、脚本及资源总结
- 移动端页面开发资源总结
- 转一篇前端开发人员总结的《JavaScript 学习资源推荐》
- Spring MVC程序中得到静态资源文件css,js,图片文件的路径问题总结