源码分析之应用加载过程解析AndroidManifest
2017-11-23 15:46
716 查看
一.SystemServer的main方法
二.SystemServer 的startBootstrapServices()方法::
SystemServer中run()方法会初始化一系列的服务,PackageManagerService就是其中之一run()方法回调用
这个时候就会调用以下方法,来初始化PackageManagerService.
三.PackageManagerService的初始化:(针对用户应用展开分析,系统应用和用户应用目录结构不同)
mian()方法被调用后会new出PackageManagerService 在其中可以发现以下目录
这几个目录就是对应apk的目录,android会扫描这几个目录,如果存在apk会解析应用.
四.解析apk:
1.解析文件:
调用private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {}
这个方法比较简单就是对apk文件进行校验,校验成功后会调用以下方法
解析出 PackageParser.Package
2.解析 AndroidManifest.xml:
此时比较重要的另外一个类就可以介绍了PackageParser,前面调用了scanPackageLI
而这个方法又调用了 public Package parsePackage(File packageFile, int flags)之后又一连串的调用最后调用到
在这个方法中我们就发现了我们即熟悉而又陌生的老朋友
继续往下看我们就会发现更多老朋友
等等不断的出现,解析整个apk后的信息存到了
这个类中
/** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); }
二.SystemServer 的startBootstrapServices()方法::
SystemServer中run()方法会初始化一系列的服务,PackageManagerService就是其中之一run()方法回调用
startBootstrapServices()
这个时候就会调用以下方法,来初始化PackageManagerService.
PackageManagerService.main()
三.PackageManagerService的初始化:(针对用户应用展开分析,系统应用和用户应用目录结构不同)
mian()方法被调用后会new出PackageManagerService 在其中可以发现以下目录
File dataDir = Environment.getDataDirectory(); mAppInstallDir = new File(dataDir, "app"); mAppLib32InstallDir = new File(dataDir, "app-lib"); mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 4000 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
这几个目录就是对应apk的目录,android会扫描这几个目录,如果存在apk会解析应用.
四.解析apk:
1.解析文件:
调用private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {}
scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags | PackageParser.PARSE_FORWARD_LOCK, scanFlags | SCAN_REQUIRE_KNOWN, 0); scanDirLI(mEphemeralInstallDir, mDefParseFlags | PackageParser.PARSE_IS_EPHEMERAL, scanFlags | SCAN_REQUIRE_KNOWN, 0);
这个方法比较简单就是对apk文件进行校验,校验成功后会调用以下方法
private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); try { return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } }
解析出 PackageParser.Package
2.解析 AndroidManifest.xml:
此时比较重要的另外一个类就可以介绍了PackageParser,前面调用了scanPackageLI
private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, ....
PackageParser pp = new PackageParser();.... pkg = pp.parsePackage(scanFile, parseFlags); ..... return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);}
而这个方法又调用了 public Package parsePackage(File packageFile, int flags)之后又一连串的调用最后调用到
private Package parseBaseApk(File apkFile, AssetManager assets, int flags) throws PackageParserException { .... Resources res = null; XmlResourceParser parser = null; .... res = new Resources(assets, mMetrics, null); parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME); final String[] outError = new String[1]; final Package pkg = parseBaseApk(res, parser, flags, outError); .... return pkg; ....... }
在这个方法中我们就发现了我们即熟悉而又陌生的老朋友
/** File name in an APK for the Android manifest. */ private static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml";
继续往下看我们就会发现更多老朋友
private Package parseBaseApkCommon(Package pkg, Set<String> acceptedTags, Resources res, XmlResourceParser parser, int flags, String[] outError) throws XmlPullParserException, IOException { ...... while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } if (tagName.equals(TAG_APPLICATION)) { ..... } else if (tagName.equals(TAG_OVERLAY)) { ..... return pkg; }
private static final String TAG_APPLICATION = "application";
private static final String TAG_USES_PERMISSION = "uses-permission";
等等不断的出现,解析整个apk后的信息存到了
/** * Holds information about dynamic settings. */ final class Settings {
这个类中
相关文章推荐
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android应用setContentView与LayoutInflater加载解析机制源码分析(转载)
- Android应用setContentView与LayoutInflater加载解析机制源码分析(超级棒!)
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android应用setContentView与LayoutInflater加载解析机制源码分析
- Android布局文件的加载过程分析:Activity.setContentView()源码分析
- [Android源码分析]蓝牙文件传输过程解析之UI实现
- Android4.4 Framework分析——Android默认Home应用Launcher3的加载过程分析
- Android 应用安装过程源码解析
- 源码分析Android 应用进程的启动过程
- Android 4.0 Launcher2源码分析——Launcher内容加载详细过程
- Android 4.0 Launcher2源码分析——Launcher内容加载详细过程
- Android OpenGL库加载过程源码分析
- android应用程序窗口框架学习(2)-view绘制流程源代码解析-setContentView与LayoutInflater加载解析机制源码分析
- Android 4.0 Launcher2源码分析——Launcher内容加载详细过程