Android 1.6 PackageParser.java 源码分析
文件目录:
android-1.6_r2\frameworks\base\core\java\android\content\pm\PackageParser.java
# PackageParser.java
1. 解析 APK 包名
public static String parsePackageName(String packageFilePath, int flags) { XmlResourceParser parser = null; AssetManager assmgr = null; try { assmgr = new AssetManager(); // 创建 AssetManager 对象 int cookie = assmgr.addAssetPath(packageFilePath); // 插入 安装包文件 路径 parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml"); // 解析 Androidmanifest.xml 文件 } catch (Exception e) { if (assmgr != null) assmgr.close(); Log.w(TAG, "Unable to read AndroidManifest.xml of " + packageFilePath, e); return null; } AttributeSet attrs = parser; String errors[] = new String[1]; String packageName = null; try { packageName = parsePackageName(parser, attrs, flags, errors); } catch (IOException e) { Log.w(TAG, packageFilePath, e); } catch (XmlPullParserException e) { Log.w(TAG, packageFilePath, e); } finally { if (parser != null) parser.close(); if (assmgr != null) assmgr.close(); } if (packageName == null) { Log.e(TAG, "parsePackageName error: " + errors[0]); return null; } return packageName; }
private static String parsePackageName(XmlPullParser parser, AttributeSet attrs, int flags, String[] outError) throws IOException, XmlPullParserException { int type; while ((type=parser.next()) != parser.START_TAG && type != parser.END_DOCUMENT) { ; } if (type != parser.START_TAG) { outError[0] = "No start tag found"; return null; } if ((flags&PARSE_CHATTY) != 0 && Config.LOGV) Log.v( TAG, "Root element name: '" + parser.getName() + "'"); if (!parser.getName().equals("manifest")) { outError[0] = "No <manifest> tag"; return null; } String pkgName = attrs.getAttributeValue(null, "package"); // 解析 package tag if (pkgName == null || pkgName.length() == 0) { outError[0] = "<manifest> does not specify package"; return null; } String nameError = validateName(pkgName, true); // 校验包名 if (nameError != null && !"android".equals(pkgName)) { // 过滤 "android" 包名 outError[0] = "<manifest> specifies bad package name \"" + pkgName + "\": " + nameError; return null; } return pkgName.intern(); }
private static String validateName(String name, boolean requiresSeparator) { final int N = name.length(); boolean hasSep = false; boolean front = true; for (int i=0; i<N; i++) { final char c = name.charAt(i); if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { front = false; continue; } if (!front) { if ((c >= '0' && c <= '9') || c == '_') { continue; } } if (c == '.') { hasSep = true; front = true; continue; } return "bad character '" + c + "'"; } return hasSep || !requiresSeparator ? null : "must have at least one '.' separator"; }
分类:
Android 1.6 源码分析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
2017-05-29 Linux命令 进程和程序
2017-05-29 Linux命令 swap:内存交换空间
2017-05-29 Linux命令 shell script的默认变量($0 , $1 , ...)
2017-05-29 Linux命令 free:查看内存使用情况
2017-05-29 Linux命令 dmesg:分析内核产生的信息
2017-05-29 Linux命令 uname:查看系统与内核相关信息