Android PluginManager 源码解析3--PluginManifestUtil


PluginManifestUtil分析

PluginManifestUtilAndroid PluginManager的一个工具类。只有一个公共方法setManifestInfo(),负责解析插件apk中的androidManifest.xml文件,并将解析的信息保存到PluginInfo中。

  • 解析PackageInfo

通过PackageManager获取插件apk文件的PackageInfo,保持在PluginInfo中。


PackageInfo pkgInfo = context.getPackageManager()
		.getPackageArchiveInfo(
				apkPath,
				PackageManager.GET_ACTIVITIES
						| PackageManager.GET_RECEIVERS//
						| PackageManager.GET_PROVIDERS//
						| PackageManager.GET_META_DATA//
						| PackageManager.GET_SHARED_LIBRARY_FILES//
		// | PackageManager.GET_SERVICES//
		// | PackageManager.GET_SIGNATURES//
		);
// Log.d("ManifestReader: setManifestInfo", "GET_SHARED_LIBRARY_FILES="
// + pkgInfo.applicationInfo.nativeLibraryDir);
info.setPackageInfo(pkgInfo);

PackageInfo保存有插件apk的包名、版本、注册的activities、services、receivers、providers、声明的权限等信息。
但是Android PluginManager目前只处理了activities、receivers。

  • 处理so文件

查找插件apk中的lib中的so文件,并解压到PluginBaseDirPluginManagerdexInternalStoragePath + pluginId+lib下面。

File libdir = ActivityOverider.getPluginLibDir(info.getId());
try {
	if(extractLibFile(zipFile, libdir)){
		pkgInfo.applicationInfo.nativeLibraryDir=libdir.getAbsolutePath();
	}
} finally {
	zipFile.close();
}

查找过程会根据设备cpu架构copy相应的文件到PluginBaseDir

  • 自定义解析manifest.xml

使用XmlManifestReader.getManifestXMLFromAPK()读取插件apk中的manifest文件,然后通过setAttrs()方法解析manifest文件,把activity、reciever、application的信息保存在PluginInfo中。


ZipFile zipFile = new ZipFile(new File(apkPath), ZipFile.OPEN_READ);
ZipEntry manifestXmlEntry = zipFile.getEntry(XmlManifestReader.DEFAULT_XML);

String manifestXML = XmlManifestReader.getManifestXMLFromAPK(zipFile,
		manifestXmlEntry);
		
...

setAttrs(info, manifestXML);
		
  • 绑定manifestXml信息到PluginInfo

分别解析application、activity、reciever、service的信息,并绑定到PluginInfo

...

do {
	switch (eventType) {
	case XmlPullParser.START_DOCUMENT: {
		break;
	}
	case XmlPullParser.START_TAG: {
		String tag = parser.getName();
		if (tag.equals("manifest")) {
			namespaceAndroid = parser.getNamespace("android");
		} else if ("activity".equals(parser.getName())) {
			addActivity(info, namespaceAndroid, parser);
		} else if ("receiver".equals(parser.getName())) {
			addReceiver(info, namespaceAndroid, parser);
		} else if ("service".equals(parser.getName())) {
			addService(info, namespaceAndroid, parser);
		}else if("application".equals(parser.getName())){
			parseApplicationInfo(info, namespaceAndroid, parser);
		}
		break;
	}
	case XmlPullParser.END_TAG: {
		break;
	}
	}
	eventType = parser.next();
} while (eventType != XmlPullParser.END_DOCUMENT);

下面已activity为例分析。

...

ResolveInfo act = new ResolveInfo();
act.activityInfo = info.findActivityByClassNameFromPkg(activityName);
do {
	switch (eventType) {
	case XmlPullParser.START_TAG: {
		String tag = parser.getName();
		if ("intent-filter".equals(tag)) {
			if (act.filter == null) {
				act.filter = new IntentFilter();
			}
		} else if ("action".equals(tag)) {
			String actionName = parser.getAttributeValue(namespace,
					"name");
			act.filter.addAction(actionName);
		} else if ("category".equals(tag)) {
			String category = parser.getAttributeValue(namespace,
					"name");
			act.filter.addCategory(category);
		} else if ("data".equals(tag)) {
			// TODO parse data
		}
		break;
	}
	}
	eventType = parser.next();
} while (!"activity".equals(parser.getName()));
//
info.addActivity(act);

模拟系统解析ResolveInfo的方式,为每一个插件apk中注册的Activity生成一个ResolveInfo,保存在PluginInfo中,供之后获取指定Intent-Filter的Activity、Service等使用。

目前对于intent-filter中的data标签没有处理。

参考

  1. ResolveInfo
  2. android ResolveInfo运用
  3. PackageInfo、ResolveInfo

文章作者: Caden
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Caden !
 上一篇
Android PluginManager 源码解析4--ActivityOverider Android PluginManager 源码解析4--ActivityOverider
ActivityOverider概述ActivityOverider负责与动态生成的PluginActivity交互。 ActivityOverider主要干了3件事: 修正StartActivity的Intent 动态生成PluginA
2015-08-12
下一篇 
Android PluginManager 源码解析2--FrameworkClassLoader Android PluginManager 源码解析2--FrameworkClassLoader
学习Android PluginManager加载插件的机制,需要先了解系统是如何加载Activity的。 Android 启动Activity的机制Android系统的Activity是通过 AndroidThread.performLa
2015-08-10
  目录