【安卓基础知识】getPackageArchiveInfo的了解

3,047 阅读3分钟

背景

前面插件热修系列中,我们是准备进入loader模块,对插件运行环境/加载机制等构建了解等,发现写着写着涉及的知识点太多,如果一口气根据shadow的流程写下来虽然可以了解里面的机制,但是如果这样的话可能会造成对知识点掌握牢固等现象,所以基于这一点打算,准备先对里面的知识点先一步步展开学习,就像当初做插件开发前的gradle的知识储备那样

API说明

public PackageInfo getPackageArchiveInfo (String archiveFilePath, int flags)

根据APK文件路径得到 PackageInfo 对象;

不过这个API将在安卓13中被废弃,改为下面API:

public PackageInfo getPackageArchiveInfo (String archiveFilePath, PackageManager.PackageInfoFlags flags) 

PackageInfo对象

官方解释是一个Apk文件中AndroidManifest.xml 的所有信息

这里我们用一张图来大致形象了解下:

1420036-4a693f8800732ca3.png

主要用于存储获取到的 Package 的一些信息,包括:包名(packageName)、版本号(versionCode)、版本名(versionName)

下面我们简单了解几个对象里面的东西

安装位置

image.png

不同的数字,代表不同的安装位置:

  • 0:系统决定的安装位置
  • 1:手机内部存储
  • 2:SD卡

在我们开发过程中可以在清单文件中设置apk的安装路径

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.ray"
      android:installLocation="auto"  // 设置了系统决定就好
      android:versionCode="1"
      android:versionName="1.0">

这里有个需要注意的是,如果需要开机启动的程序,一定要安装到手机内存中;

因为开机启动的广播消息BOOT_COMPLETE早于 SD的启动,如果将程序安装到SD卡,无法接收到开机广播。

权限列表

image.png

清单文件下所有的权限列表

一般情况我们可以通过下面代码获取安装App的权限

image.png

ApplicationInfo

该对象为 PackageInfo 的成员变量

Apk 定义在 AndroidManifest.xml 中的一些信息,如:

  • packageName:包名
  • targetSdkVersion:目标 SDK 版本。
  • minSdkVersion:最小支持 SDK 版本,有 Api 限制,最低在 Api Level 24 及以上支持。
  • sourceDir:App 的 Apk 源文件存放的目录。
  • dataDir:data 目录的全路径。
  • metaData:Manifest 中定义的 meta 标签数据。
  • uid:当前 App 分配的 uid
  • nativeLibraryDir:so的加载目录

在shadow构建插件PackageInfo的时候,就有对成员变量ApplicationInfo赋值

image.png

其他类似成员对象:ActivityInfo / ServiceInfo / ProviderInfo

它们就是 Android 定义的四大组件中的几个,不展开细讲,需要了解的具体戳这里>>>

PackageInfo几个简单用途

获取所有安装的 App

public static List<PackageInfo> getDeviceApp(Context context) {
   return context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES);
}

GET_ACTIVITIES 是一个 flags 的字段,不同的flags代表不同的意思

GET_ACTIVITIES :值为1.
如果想获得所有<activity>标签的信息,需要传入这个值.然后通过PackageInfo.

GET_GIDS:值为256.
获得group id的信息.

GET_CONFIGURATIONS:值16384.
获得<uses-configuration>标签和<uses-feature>标签的信息.

GET_INSTRUMENTATION:值16.
获得<instrumentation>标签的信息

GET_PERMISSIONS:值4096.
获得<permission>标签的信息.

GET_PROVIDERS:值8.
获得<provider>标签的信息

GET_RECEIVERS:值2.
获得<receive>标签的信息

GET_SERVICES:值4.
获得<service>标签的信息

GET_SIGNATURES:值64.
获得认证的信息.

GET_UNINSTALLED_PACKAGES:值8192.
如果有没安装的apk,一起获得包信息。

更多细节可以戳这里>>>

判断 App 是否安装

 public static boolean isInstalled(Context context, String pkg) {
        //默认不存在
        boolean exit = false;
        try {
            //不为空则存在
            exit = context.getPackageManager().getPackageInfo(pkg, PackageManager.GET_ACTIVITIES) != null;
        } catch (PackageManager.NameNotFoundException e) {
        }
        return exit;
}

去获取 PackageInfo ,如果能拿回来数据,就说明是有安装的

其它获取信息方式

其它如:App名称/版本等不展开,细节戳这里>>>>

Shadow那边的使用

image.png

image.png

很明显shadow在模拟系统在构建插件的PackageInfo对象

这样前面我们了解了PackageInfo对象情况,反过来理解插件这样做的意义就明白了

结尾

此篇就到这,后面继续加油~