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

邮箱:[email protected]


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

应该明确的问题

  • 插件化是什么意思?
  • 为什么要使用插件化的这种方式?
  • 插件化的优劣?

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

  • 插件顾名思义就是讲某一个东西拆分,App也一样可以拆分,原因有很多例如方法数的限制(65535是因为int本身的限制),app过大,性能损耗过于严重等等
  • 插件化就是为了解决这类问题出现的
  • 插件化的优点:模块解耦,动态升级,高效的并行开发,按需求进行加载等等

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

需要的知识储备

  1. 反射相关
  2. ClassLoader的原理以及基本使用
  3. 代理模式等暂时就需要那么多,

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


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

整体的思路

  1. 首先我们需要先找到已经加载的apk(apk之间本身是互不相通的,我们可以在manifest节点上设置shareUsersId,这样我们的apk就可以在同一个运行区域内获取相关内容)
  2. 之后我们通过packageManager来获取已经安装的app
  3. 最重要的就是我们需要取到apk对应的Context或者Re
  4. 我们利用反射拿到资源id
  5. 通过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(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的资源
有什么问题可以问我

猜你喜欢

转载自blog.csdn.net/xiangnicao/article/details/71440617