Android 动态加载 之 如何获取插件res资源
来源:互联网 发布:八岐大蛇 蓝牙 mac 编辑:程序博客网 时间:2024/06/05 17:08
直接上干货:
PackageManager pm = mContext.getPackageManager(); PackageInfo pi = pm.getPackageArchiveInfo(mFilename, 0); mNewResources = pm.getResourcesForApplication(pi.applicationInfo);
要获取插件的资源信息我们采用的是通过实例packageInfo,并动态的更改里边的sourceDir和publicSourceDir为插件Apk路径地址。
而这里关键的是什么时候去加载的资源信息呢:
1,pm.getPackageArchiveInfo
public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) { PackageParser packageParser = new PackageParser(archiveFilePath); DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); final File sourceFile = new File(archiveFilePath); PackageParser.Package pkg = packageParser.parsePackage( sourceFile, archiveFilePath, metrics, 0); if (pkg == null) { return null; } if ((flags & GET_SIGNATURES) != 0) { packageParser.collectCertificates(pkg, 0); } PackageUserState state = new PackageUserState(); return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0, null, state); }
如图,在执行取packageArchiveInfo的时候,回去解析包文件,具体看源码:
493 public Package parsePackage(File sourceFile, String destCodePath,494 DisplayMetrics metrics, int flags) {495 mParseError = PackageManager.INSTALL_SUCCEEDED;496497 mArchiveSourcePath = sourceFile.getPath();498 if (!sourceFile.isFile()) {499 Slog.w(TAG, "Skipping dir: " + mArchiveSourcePath);500 mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;501 return null;502 }503 if (!isPackageFilename(sourceFile.getName())504 && (flags&PARSE_MUST_BE_APK) != 0) {505 if ((flags&PARSE_IS_SYSTEM) == 0) {506 // We expect to have non-.apk files in the system dir,507 // so don't warn about them.508 Slog.w(TAG, "Skipping non-package file: " + mArchiveSourcePath);509 }510 mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;511 return null;512 }513514 if (DEBUG_JAR)515 Slog.d(TAG, "Scanning package: " + mArchiveSourcePath);516517 XmlResourceParser parser = null;518 AssetManager assmgr = null;519 Resources res = null;520 boolean assetError = true;521 try {522 assmgr = new AssetManager();523 int cookie = assmgr.addAssetPath(mArchiveSourcePath);524 if (cookie != 0) {525 res = new Resources(assmgr, metrics, null);526 assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,527 Build.VERSION.RESOURCES_SDK_INT);528 parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);529 assetError = false;530 } else {531 Slog.w(TAG, "Failed adding asset path:"+mArchiveSourcePath);532 }533 } catch (Exception e) {534 Slog.w(TAG, "Unable to read AndroidManifest.xml of "535 + mArchiveSourcePath, e);536 }537 if (assetError) {538 if (assmgr != null) assmgr.close();539 mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;540 return null;541 }542 String[] errorText = new String[1];543 Package pkg = null;544 Exception errorException = null;545 try {546 // XXXX todo: need to figure out correct configuration.547 pkg = parsePackage(res, parser, flags, errorText);548 } catch (Exception e) {549 errorException = e;550 mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;551 }552553554 if (pkg == null) {555 // If we are only parsing core apps, then a null with INSTALL_SUCCEEDED556 // just means to skip this app so don't make a fuss about it.557 if (!mOnlyCoreApps || mParseError != PackageManager.INSTALL_SUCCEEDED) {558 if (errorException != null) {559 Slog.w(TAG, mArchiveSourcePath, errorException);560 } else {561 Slog.w(TAG, mArchiveSourcePath + " (at "562 + parser.getPositionDescription()563 + "): " + errorText[0]);564 }565 if (mParseError == PackageManager.INSTALL_SUCCEEDED) {566 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;567 }568 }569 parser.close();570 assmgr.close();571 return null;572 }573574 parser.close();575 assmgr.close();576577 // Set code and resource paths578 pkg.mPath = destCodePath;579 pkg.mScanPath = mArchiveSourcePath;580 //pkg.applicationInfo.sourceDir = destCodePath;581 //pkg.applicationInfo.publicSourceDir = destRes;582 pkg.mSignatures = null;583584 return pkg;585 }过程中实例了AssetManager 和Resources
这样在后边调用的时候无论是实例新的ContextThemeWrapper,还是取用资源对象都可以通过getResources()拿到,供动态加载插件资源所用。
2 0
- Android 动态加载 之 如何获取插件res资源
- Android插件化之资源动态加载
- Android获取res资源
- 如何获取 res 中的资源
- Android 中获取res资源
- Android中获取res(xml,color)资源
- 获取资源文件, Android res getIdentifier
- Android动态加载—Res文件
- android动态加载资源
- 编程回忆之Android回忆(Android获取res目录下的资源)
- res资源获取
- Android插件-动态加载
- Android如何加载插件APK里面的资源
- Android插件化架构设计之加载资源文件
- android 中的 res 资源
- Android 资源(res)混淆
- android res 资源简介
- Android res 资源文件
- android 从零开始搭建框架系列(1)
- PHP导出excel
- 13-高亮基础
- 实例化bean
- objective-c第十章练习答案
- Android 动态加载 之 如何获取插件res资源
- CocoaPods 安装 与 使用
- 二叉树
- Java字符集检测,更好的支持中文字符集
- Shell日志分析常用命令和例子
- hdu~3530(单调队列)
- 数组去重
- Linux下安装mysql-5.6.4 的图文教程
- IOS 高机动画详解及实例