Android中的Resources解析
来源:互联网 发布:mysql 状态 编辑:程序博客网 时间:2024/06/08 17:08
下面我们从Application的创建说起
/frameworks/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) { // 1.1 获取应用信息LoadedApk data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); // 1.2、创建Application的Context final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); // ......}
一、获取应用信息LoadedApk
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, CompatibilityInfo compatInfo) { return getPackageInfo(ai, compatInfo, null, false, true, false);}
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, boolean includeCode, boolean registerPackage) { synchronized (mResourcesManager) { WeakReference<LoadedApk> ref; // 这里就可以看到,LoadedApk会缓存在mPackages中,如果为null,就会创建一个,之后就不需要创建了 if (includeCode) { ref = mPackages.get(aInfo.packageName); } else { ref = mResourcePackages.get(aInfo.packageName); } LoadedApk packageInfo = ref != null ? ref.get() : null; if (packageInfo == null || (packageInfo.mResources != null && !packageInfo.mResources.getAssets().isUpToDate())) { packageInfo = new LoadedApk(this, aInfo, compatInfo, baseLoader, securityViolation, includeCode && (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage); if (mSystemThread && "android".equals(aInfo.packageName)) { packageInfo.installSystemApplicationInfo(aInfo, getSystemContext().mPackageInfo.getClassLoader()); } if (includeCode) { mPackages.put(aInfo.packageName, new WeakReference<LoadedApk>(packageInfo)); } else { mResourcePackages.put(aInfo.packageName, new WeakReference<LoadedApk>(packageInfo)); } } return packageInfo; }}
二、创建Application的Context
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); // 直接创建一个ContextImpl对象 return new ContextImpl(null, mainThread, packageInfo, null, null, false, null, null);}
/frameworks/base/core/java/android/app/ContextImpl.java
private ContextImpl(ContextImpl container, ActivityThread mainThread, LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted, Display display, Configuration overrideConfiguration) { mOuterContext = this; mMainThread = mainThread; mActivityToken = activityToken; mRestricted = restricted; if (user == null) { user = Process.myUserHandle(); } mUser = user; mPackageInfo = packageInfo; mResourcesManager = ResourcesManager.getInstance(); mDisplay = display; mOverrideConfiguration = overrideConfiguration; final int displayId = getDisplayId(); CompatibilityInfo compatInfo = null; if (container != null) { compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo(); } if (compatInfo == null && displayId == Display.DEFAULT_DISPLAY) { compatInfo = packageInfo.getCompatibilityInfo(); } mDisplayAdjustments.setCompatibilityInfo(compatInfo); mDisplayAdjustments.setActivityToken(activityToken); //packageInfo为LoadedApk对象,也就是这里调用了LoadedApk的getResources方法 Resources resources = packageInfo.getResources(mainThread); if (resources != null) { if (activityToken != null || displayId != Display.DEFAULT_DISPLAY || overrideConfiguration != null || (compatInfo != null && compatInfo.applicationScale != resources.getCompatibilityInfo().applicationScale)) { resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(), packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(), packageInfo.getApplicationInfo().sharedLibraryFiles, displayId, overrideConfiguration, compatInfo, activityToken); } } mResources = resources; if (container != null) { mBasePackageName = container.mBasePackageName; mOpPackageName = container.mOpPackageName; } else { mBasePackageName = packageInfo.mPackageName; ApplicationInfo ainfo = packageInfo.getApplicationInfo(); if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) { // Special case: system components allow themselves to be loaded in to other // processes. For purposes of app ops, we must then consider the context as // belonging to the package of this process, not the system itself, otherwise // the package+uid verifications in app ops will fail. mOpPackageName = ActivityThread.currentPackageName(); } else { mOpPackageName = mBasePackageName; } } mContentResolver = new ApplicationContentResolver(this, mainThread, user);}
/frameworks/base/core/java/android/app/LoadedApk.java
public Resources getResources(ActivityThread mainThread) { if (mResources == null) { // 可以看到直接调用的是ActivityThread的getTopLevelResources方法 mResources = mainThread.getTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs, mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null, this); } return mResources;}
/frameworks/base/core/java/android/app/ActivityThread.java
Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, String[] libDirs, int displayId, Configuration overrideConfiguration, LoadedApk pkgInfo) { // 可以看到直接调用的是ResourcesManager的getTopLevelResources方法 return mResourcesManager.getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs, displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);}
ActivityThread() { mResourcesManager = ResourcesManager.getInstance();}
/frameworks/base/core/java/android/app/ResourcesManager.java
// ResourcesManager是一个单例类,也就是说只会有一份,所以我们所有资源的获取最终调用的都是这个对象public static ResourcesManager getInstance() { synchronized (ResourcesManager.class) { if (sResourcesManager == null) { sResourcesManager = new ResourcesManager(); } return sResourcesManager; }}
阅读全文
0 0
- Android中的Resources解析
- Android ApiDemos示例解析(48):Content->Resources->Resources
- Android读取Resources和Assets中的文件
- Android中的Resources$NotFoundException: Resource ID 问题
- Android ApiDemos示例解析(49):Content->Resources->Styled Text
- Android ApiDemos示例解析(50):Content->Resources->External Storage
- Resources 方法解析
- SilverLight中的Resources
- resources中的color 设置
- Android: Android Resources
- android中的dom解析
- android中的pull解析
- ANDROID 中的xml解析
- 解析Android中的XML
- android中的Json解析
- android 中的Service 解析
- Android中的Handler解析
- Android中的XML解析
- java 线程间通信,多生产者多消费者问题
- 链表的插入、删除
- 一些常用的adb命令
- Linux内核学习记录1
- 1032. 挖掘机技术哪家强(20)
- Android中的Resources解析
- MFC窗口销毁过程
- Linux终端下 dstat 监控工具
- Java内存区域
- 《算法图解》第五章散列函数和散列表
- 零基础如何迅速学习html5?
- LeetCode.718 Maximum Length of Repeated Subarray(经典DP问题)
- 随笔记下100个常用JS
- 关于vector二维动态数组初始化