您的位置:首页 > 移动开发 > Android开发

Android插件化基础之加载已安装的apk资源

2017-05-09 11:34 323 查看
邮箱:Jack120612@163.com

我也是在进行学习和研究,有问题可以直接说

应该明确的问题

插件化是什么意思?

为什么要使用插件化的这种方式?

插件化的优劣?

根据上述问题我们就可以进行初步的了解了

插件顾名思义就是讲某一个东西拆分,App也一样可以拆分,原因有很多例如方法数的限制(65535是因为int本身的限制),app过大,性能损耗过于严重等等

插件化就是为了解决这类问题出现的

插件化的优点:模块解耦,动态升级,高效的并行开发,按需求进行加载等等

大概了解一下之后我们就开始进入基础的学习

需要的知识储备

反射相关

ClassLoader的原理以及基本使用

代理模式等暂时就需要那么多,

废话不多说 直接上代码 先做出来点东西再去仔细研究代码

先来学习一下如何加载已经安装的apk的资源

整体的思路

首先我们需要先找到已经加载的apk(apk之间本身是互不相通的,我们可以在manifest节点上设置shareUsersId,这样我们的apk就可以在同一个运行区域内获取相关内容)

之后我们通过packageManager来获取已经安装的app

最重要的就是我们需要取到apk对应的Context或者Re

我们利用反射拿到资源id

通过Context拿到对应的资源就可以了

思路简单 实现起来也不是很难

大家看一下代码

ArrayList<InfoBean> labels = new ArrayList<>();
PackageManager pm = getPackageManager();
//拿到已经安装的列表
List<PackageInfo> installedPackages = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
for (PackageInfo info :
installedPackages) {
String packageName = info.packageName;
String sharedUserId = info.sharedUserId;

if(!TextUtils.isEmpty(sharedUserId)&&sharedUserId.equals("com.test.download")&&!packageName.equals(getPackageName())){
String label = pm.getApplicationLabel(info.applicationInfo).toString();
InfoBean bean = new InfoBean(label,packageName);
labels.add(bean);
}

}
//展示相关信息
showData(labels.get(0).label);
showData(labels.get(
4000
0).name);
//加载已经安装的apk文件并且找到其资源
//通过PathClassLoader进行加载
try {
//根据包名来创建对应的 参数一应用的lable  参数二第一个忽略警告第二个包含代码运行
Context pkgContext = this.createPackageContext(labels.get(0).label,CONTEXT_IGNORE_SECURITY|CONTEXT_INCLUDE_CODE);
//创建PathClassLoader该类加载器可以加载已经安装过的app 参数一路径 参数二父类加载器 一般都个ClassLoader.getSystemClassLoader()
PathClassLoader loader = new PathClassLoader(pkgContext.getPackageResourcePath(),ClassLoader.getSystemClassLoader());
//通过反射拿到drawable
Class<?> clazz = Class.forName(labels.get(0).label+".R$drawable", true, loader);
//拿到资源信息
Field about = clazz.getDeclaredField("about");
int res = about.getInt(R.drawable.class);

Drawable drawable = pkgContext.getResources().getDrawable(res);
drawListView.setBackground(drawable);


InfoBean只是一个简单信息的实体类,代码很简单,我就不贴出来了

说一下核心方法

this.createPackageContext()该方法会返回一个对应包的Context我们可以通过这个来得到资源文件

PathClassLoader loader = new PathClassLoader()我们可以通过加载器来加载已经安装过得apk

Field about = clazz.getDeclaredField(“about”);

int res = about.getInt(R.drawable.class);我们可以通过Field来获取图片资源

pkgContext.getResources().getDrawable(res);利用已经获取到的

上下文来获取对应的图片资源

以上就是简单的实现

这个只是个demo练习学习用的

之后我还会写一篇基础的获取未安装的apk的资源

有什么问题可以问我
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐