LOCAL_PRIVILEGED_MODULE 详解(2)

来源:互联网 发布:sql declare 编辑:程序博客网 时间:2024/06/14 23:27

2.安装时作用

2.1 准备知识

在介绍LOCAL_PRIVILEGED_MODULE在安装时的作用之前,先介绍几个关键的准备知识:
(1)packages.xml
这个文件位于ROM设备的 data/system,读取需要root权限。记录系统中所有安装的应用信息,包含基本信息、签名和权限等。
举几个关键字段为例:
name 包名
codePath 应用安装的路径,非系统应用一般在/data/app/xxx,或者SD卡上;系统应用一般在/system/app/xxx或/system/priv-app/xxx
nativeLibraryPath 应用中本地库安装路径,一般在codePath/lib
version 版本号
userId/sharedUserId 应用的userId
(2)PMS的扫描(scan)与安装(install)
PMS,即PackageManagerService,是安卓框架层核心系统服务之一,常驻内存,实现与app安装、卸载相关功能。PMS对应的主要源代码为 frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java。下面部分内容引自刘超《深入解析Android5.0系统》中对于PMS的总结。
扫描:PMS启动的时候,会扫描所有的apk文件和jar包,把它们的信息读取出来,保存在内存中。扫描过程中如果遇到没有优化的文件,会执行转换,将app文件从dex格式转成odex。扫描的逻辑在PMS构造方法中调用,下面是构造方法中的一部分相关逻辑:

    public PackageManagerService(Context context, Installer installer,            boolean factoryTest, boolean onlyCore) {            ......            // Collect vendor overlay packages.            // (Do this before scanning any apps.)            // For security and version matching reason, only consider            // overlay packages if they reside in VENDOR_OVERLAY_DIR.            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);            scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);            // Find base frameworks (resource packages without code).            scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR                    | PackageParser.PARSE_IS_PRIVILEGED,                    scanFlags | SCAN_NO_DEX, 0);            // Collected privileged system packages.            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");            scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);            // Collect ordinary system packages.            final File systemAppDir = new File(Environment.getRootDirectory(), "app");            scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);            // Collect all vendor packages.            File vendorAppDir = new File("/vendor/app");            try {                vendorAppDir = vendorAppDir.getCanonicalFile();            } catch (IOException e) {                // failed to look up canonical path, continue with original one            }            scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);            // Collect all OEM packages.            final File oemAppDir = new File(Environment.getOemDirectory(), "app");            scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);            ......     }

安装:主要分为两个阶段,第一阶段是复制文件,把需要安装的apk复制到 /data/app;第二阶段是装载应用,把应用转成odex,为应用创建数据目录,把应用的信息装载进PMS的数据结构中。
非系统应用和系统应用的区别在于,系统应用并不存在安装的阶段,系统应用是随ROM出厂烧写到手机设备上,位于 system/app和system/priv-app。
(3)PMS对外提供的信息查询接口
由(2)可知,通过扫描和安装,PMS已经将应用的信息装载到了内存。我们知道,Android的公开API中有各种各样的XXXManager,第三方应用可以使用它们很方便地获取各种信息和能力。这些Manager大都在后台对应着某个系统应用。PMS的前台就是大名鼎鼎的PackageManager。所以你通过调用PackageManager查询某个应用的相关信息,实际上使用的就是PMS(2)中得到的缓存。举一个例子,下面代码通过PackageManager公开接口获取微信的一些信息:

    private void test2() {        PackageManager packageManager = getApplicationContext().getPackageManager();        try {            PackageInfo packageInfo = packageManager.getPackageInfo("com.tencent.mm",                    PackageManager.GET_ACTIVITIES);            Log.i("TEST_PMR", "packageName : " + packageInfo.packageName);            Log.i("TEST_PMR", "versionName : " + packageInfo.versionName);            Log.i("TEST_PMR", "versionCode : " + packageInfo.versionCode);            Log.i("TEST_PMR", "sharedUserId : " + packageInfo.sharedUserId);            Log.i("TEST_PMR", "dataDir : " + packageInfo.applicationInfo.dataDir);            Log.i("TEST_PMR", "nativeLibraryDir : " + packageInfo.applicationInfo.nativeLibraryDir);        } catch (PackageManager.NameNotFoundException e) {            e.printStackTrace();        }    }

输出:

07-17 20:20:50.599 14661 14661 I TEST_PMR: packageName : com.tencent.mm07-17 20:20:50.600 14661 14661 I TEST_PMR: versionName : 6.5.1007-17 20:20:50.600 14661 14661 I TEST_PMR: versionCode : 108007-17 20:20:50.600 14661 14661 I TEST_PMR: sharedUserId : null07-17 20:20:50.600 14661 14661 I TEST_PMR: dataDir : /data/user/0/com.tencent.mm07-17 20:20:50.600 14661 14661 I TEST_PMR: nativeLibraryDir : /data/app/com.tencent.mm-1/lib/arm

LOCAL_PRIVILEGED_MODULE 详解(1)
LOCAL_PRIVILEGED_MODULE 详解(2)
LOCAL_PRIVILEGED_MODULE 详解(3)
LOCAL_PRIVILEGED_MODULE 详解(4)
LOCAL_PRIVILEGED_MODULE 详解(5)

原创粉丝点击