当前位置:   article > 正文

android中是如何对包进行解析--解析ContentProvider_android解析 app 发送的数据包

android解析 app 发送的数据包

如果了解过android的启动流程,我们知道android在启动的时候会去解析/data/system和/data/app下已经存在的apk。

那么是从哪里开始对这些包进行解析的呢?

1.

  1. public static final IPackageManager main(Context context, Installer installer,
  2. boolean factoryTest, boolean onlyCore) {
  3. PackageManagerService m = new PackageManagerService(context, installer,
  4. factoryTest, onlyCore);
  5. ServiceManager.addService("package", m);
  6. return m;
  7. }
android在启动的时候,会根据init.rc配置文件去执行PackageManagerService中的main方法。

该方法的操作很简单,就是生成一个PackageManagerService的对象,然后加载到ServiceManager进程中进行管理。

从这里我们就可以看出,ServiceManager进程就是用来管理android中Framework层的一些系统Service。


2.

main方法中代码很少,那么PackageManagerService是在哪里解析包的呢?

实际上在new一个PackageManagerService对象的时候,就对已存在的apk进行了解析。

下面我们对/data/app/下的apk解析过程做一个分析。

  1. synchronized (mPackages) {
  2. mHandlerThread.start();
  3. mHandler = new PackageHandler(mHandlerThread.getLooper());
  4. File dataDir = Environment.getDataDirectory();
  5. mAppDataDir = new File(dataDir, "data");
  6. mAppInstallDir = new File(dataDir, "app");
  7. mAppLibInstallDir = new File(dataDir, "app-lib");
  8. mAsecInternalPath = new File(dataDir, "app-asec").getPath();
  9. mUserAppDataDir = new File(dataDir, "user");
  10. mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
  11. sUserManager = new UserManagerService(context, this,
  12. mInstallLock, mPackages);
在这里对android的一些路径进行了获取,这里我们就看到android默认的用户安装路径mAppInstallDir就是/data/app/。

知道用户的apk所在路径,下面就可以去遍历该路径下的所有apk,然后进行解析。

  1. if (!mOnlyCore) {
  2. EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
  3. SystemClock.uptimeMillis());
  4. mAppInstallObserver = new AppDirObserver(
  5. mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
  6. mAppInstallObserver.startWatching();
  7. scanDirLI(mAppInstallDir, 0, scanMode, 0);
  8. mDrmAppInstallObserver = new AppDirObserver(
  9. mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
  10. mDrmAppInstallObserver.startWatching();
  11. scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
  12. scanMode, 0);

通过上面的scanDirLI方法,对/data/app/下面的apk进行遍历。
  1. private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
  2. String[] files = dir.list();
  3. if (files == null) {
  4. Log.d(TAG, "No files in app dir " + dir);
  5. return;
  6. }
  7. if (DEBUG_PACKAGE_SCANNING) {
  8. Log.d(TAG, "Scanning app dir " + dir);
  9. }
  10. int i;
  11. for (i=0; i<files.length; i++) {
  12. File file = new File(dir, files[i]);
  13. if (!isPackageFilename(files[i])) {
  14. // Ignore entries which are not apk's
  15. continue;
  16. }
  17. PackageParser.Package pkg = scanPackageLI(file,
  18. flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
  19. // Don't mess around with apps in system partition.
  20. if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
  21. mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
  22. // Delete the apk
  23. Slog.w(TAG, "Cleaning up failed install of " + file);
  24. file.delete();
  25. }
  26. }
  27. }
通过dir.list()我们得到/data/app/下所有的文件名,然后在后面的for循环中逐个判断是否是*.apk文件,如果是,就调用scanPackageLI进行解析;

如果不是,就继续循环,寻找下一个apk文件。


下面进入scanPackageLI

  1. private PackageParser.Package scanPackageLI(File scanFile,
  2. int parseFlags, int scanMode, long currentTime, UserHandle user) {
  3. mLastScanError = PackageManager.INSTALL_SUCCEEDED;
  4. String scanPath = scanFile.getPath();
  5. parseFlags |= mDefParseFlags;
  6. PackageParser pp = new PackageParser(scanPath);
  7. pp.setSeparateProcesses(mSeparateProcesses);
  8. pp.setOnlyCoreApps(mOnlyCore);
  9. final PackageParser.Package pkg = pp.parsePackage(scanFile,
  10. scanPath, mMetrics, parseFlags);
  11. if (pkg == null) {
  12. mLastScanError = pp.getParseError();
  13. return null;
  14. }
  15. PackageSetting ps = null;
  16. PackageSetting updatedPkg;

scanPackageLI返回PackageParser.Package类型的值,里面存储了对应apk的解析出来的信息。

  1. final PackageParser.Package pkg = pp.parsePackage(scanFile,
  2. scanPath, mMetrics, parseFlags);
这里就是去解析apk文件,从scanpackageLI的代码看出pp实际是一个PackageParser对象。


3. PackageParser.java

上面的pp.parsePackage会调用如下:

  1. try {
  2. // XXXX todo: need to figure out correct configuration.
  3. pkg = parsePackage(res, parser, flags, errorText);
  4. } catch (Exception e) {
  5. errorException = e;
  6. mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
  7. }

这里调用重载的parsePackage方法。

在这里面回去分析AndroidManifest.xml文件,当获取到application标签时,回去解析下面存在的控件。

  1. if (tagName.equals("application")) {
  2. if (foundApp) {
  3. if (RIGID_PARSER) {
  4. outError[0] = "<manifest> has more than one <application>";
  5. mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
  6. return null;
  7. } else {
  8. Slog.w(TAG, "<manifest> has more than one <application>");
  9. XmlUtils.skipCurrentTag(parser);
  10. continue;
  11. }
  12. }
  13. foundApp = true;
  14. if (!parseApplication(pkg, res, parser, attrs, flags, outError)) {
  15. return null;
  16. }
parseApplication就是去解析标签<application>中的资源。

下面我们来看一下parseApplication是怎么解析provider的。

  1. while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
  2. && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
  3. if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
  4. continue;
  5. }
  6. String tagName = parser.getName();
  7. if (tagName.equals("activity")) {
  8. Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false,
  9. hardwareAccelerated);
  10. if (a == null) {
  11. mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
  12. return false;
  13. }
  14. owner.activities.add(a);
  15. } else if (tagName.equals("receiver")) {
  16. Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true, false);
  17. if (a == null) {
  18. mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
  19. return false;
  20. }
  21. owner.receivers.add(a);
  22. } else if (tagName.equals("service")) {
  23. Service s = parseService(owner, res, parser, attrs, flags, outError);
  24. if (s == null) {
  25. mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
  26. return false;
  27. }
  28. owner.services.add(s);
  29. } else if (tagName.equals("provider")) {
  30. Provider p = parseProvider(owner, res, parser, attrs, flags, outError);
  31. if (p == null) {
  32. mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
  33. return false;
  34. }
  35. owner.providers.add(p);
  36. }

我们看到上面会根据获取到不同的标签文件去解析不同的东西。

当我们的标签是provider时,就会调用parseProvider去解析。解析完成后就会把得到的Provider加入到owner.provider中。


  1. private Provider parseProvider(Package owner, Resources res,
  2. XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
  3. throws XmlPullParserException, IOException {
  4. TypedArray sa = res.obtainAttributes(attrs,
  5. com.android.internal.R.styleable.AndroidManifestProvider);
  6. if (mParseProviderArgs == null) {
  7. mParseProviderArgs = new ParseComponentArgs(owner, outError,
  8. com.android.internal.R.styleable.AndroidManifestProvider_name,
  9. com.android.internal.R.styleable.AndroidManifestProvider_label,
  10. com.android.internal.R.styleable.AndroidManifestProvider_icon,
  11. com.android.internal.R.styleable.AndroidManifestProvider_logo,
  12. mSeparateProcesses,
  13. com.android.internal.R.styleable.AndroidManifestProvider_process,
  14. com.android.internal.R.styleable.AndroidManifestProvider_description,
  15. com.android.internal.R.styleable.AndroidManifestProvider_enabled);
  16. mParseProviderArgs.tag = "<provider>";
  17. }
  18. mParseProviderArgs.sa = sa;
  19. mParseProviderArgs.flags = flags;
  20. Provider p = new Provider(mParseProviderArgs, new ProviderInfo());
  21. if (outError[0] != null) {
  22. sa.recycle();
  23. return null;
  24. }
  25. boolean providerExportedDefault = false;
  26. if (owner.applicationInfo.targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR1) {
  27. // For compatibility, applications targeting API level 16 or lower
  28. // should have their content providers exported by default, unless they
  29. // specify otherwise.
  30. providerExportedDefault = true;
  31. }
  32. p.info.exported = sa.getBoolean(
  33. com.android.internal.R.styleable.AndroidManifestProvider_exported,
  34. providerExportedDefault);
  35. String cpname = sa.getNonConfigurationString(
  36. com.android.internal.R.styleable.AndroidManifestProvider_authorities, 0);
  37. p.info.isSyncable = sa.getBoolean(
  38. com.android.internal.R.styleable.AndroidManifestProvider_syncable,
  39. false);
  40. String permission = sa.getNonConfigurationString(
  41. com.android.internal.R.styleable.AndroidManifestProvider_permission, 0);
  42. String str = sa.getNonConfigurationString(
  43. com.android.internal.R.styleable.AndroidManifestProvider_readPermission, 0);
  44. if (str == null) {
  45. str = permission;
  46. }
  47. if (str == null) {
  48. p.info.readPermission = owner.applicationInfo.permission;
  49. } else {
  50. p.info.readPermission =
  51. str.length() > 0 ? str.toString().intern() : null;
  52. }
  53. str = sa.getNonConfigurationString(
  54. com.android.internal.R.styleable.AndroidManifestProvider_writePermission, 0);
  55. if (str == null) {
  56. str = permission;
  57. }
  58. if (str == null) {
  59. p.info.writePermission = owner.applicationInfo.permission;
  60. } else {
  61. p.info.writePermission =
  62. str.length() > 0 ? str.toString().intern() : null;
  63. }
  64. p.info.grantUriPermissions = sa.getBoolean(
  65. com.android.internal.R.styleable.AndroidManifestProvider_grantUriPermissions,
  66. false);
  67. p.info.multiprocess = sa.getBoolean(
  68. com.android.internal.R.styleable.AndroidManifestProvider_multiprocess,
  69. false);
  70. p.info.initOrder = sa.getInt(
  71. com.android.internal.R.styleable.AndroidManifestProvider_initOrder,
  72. 0);
  73. p.info.flags = 0;
  74. if (sa.getBoolean(
  75. com.android.internal.R.styleable.AndroidManifestProvider_singleUser,
  76. false)) {
  77. p.info.flags |= ProviderInfo.FLAG_SINGLE_USER;
  78. if (p.info.exported) {
  79. Slog.w(TAG, "Provider exported request ignored due to singleUser: "
  80. + p.className + " at " + mArchiveSourcePath + " "
  81. + parser.getPositionDescription());
  82. p.info.exported = false;
  83. }
  84. }
  85. sa.recycle();
  86. if ((owner.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
  87. // A heavy-weight application can not have providers in its main process
  88. // We can do direct compare because we intern all strings.
  89. if (p.info.processName == owner.packageName) {
  90. outError[0] = "Heavy-weight applications can not have providers in main process";
  91. return null;
  92. }
  93. }
  94. if (cpname == null) {
  95. outError[0] = "<provider> does not include authorities attribute";
  96. return null;
  97. }
  98. p.info.authority = cpname.intern();
  99. if (!parseProviderTags(res, parser, attrs, p, outError)) {
  100. return null;
  101. }
  102. return p;
  103. }

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号