如何应对Android面试官 -> PKMS 权限管理

Android PackageManagerService总结(二) PKMS启动过程 PackageManagerService(简称PKMS),是Android系统中核心服务之一,管理着所有与package相关的工作,常见的比如安装、卸载应用, 信息查询等工作 阅读详情

前言


image.png

本章我们继续上一章节,讲解 PKMS 相关知识点;

静默安装


静默安装说的就是:在用户无感知的情况下,给用户的手机安装了某个 app,或者是用户触发安装之后,不需要额外的任何操作即可以安装目标 app 到手机上的行为;

手机内置的应用市场 app,其实现了静默安装的能力,三方 app 如果想实现这个能力是不可能的。因为需要系统的签名,这个签名厂商是不会开放的,所以我们无法实现想要的静默安装能力;

签名

那么,这个签名是什么呢?就是在 PKMS 的构造方法中,添加到系统 Settings 的 UID

mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.se", SE_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

这里额外插入一个小的知识点,如果做系统应用开发,如何让系统应用在系统启动的时候被装载进来,需要使用 adb push 相关命令;

1. adb remount
2. adb shell
3. chmod777 system/app
4. exit
5. adb push xxx/yy.apk system/app
6. adb reboot

这里 xxx/yy.apk 是 apk 的绝对路径,system/app 是系统目录;这些操作的本质就是:拷贝 + 扫描,将你定制的系统应用拷贝到 system/app 中然后重启系统执行扫描操作;

厂商静默安装实现

如果想实现系统的『静默安装』能力,我们需要准备哪些能力呢?首先我们需要三个系统的 aidl 文件;

android.content.pm.IPackageDeleteObserver.aidl
android.content.pm.IPackageInstallObserver.aidl
android.content.pm.IPackageMoveObserver.aidl

/**
 * API for deletion callbacks from the Package Manager.
 *
 * {@hide}
 */
oneway interface IPackageDeleteObserver {
    void packageDeleted(in String packageName, in int returnCode);
}
/**
 * API for installation callbacks from the Package Manager.
 * @hide
 */
oneway interface IPackageInstallObserver {
    void packageInstalled(in String packageName, int returnCode);
}
/**
 * Callback for moving package resources from the Package Manager.
 * @hide
 */
oneway interface IPackageMoveObserver {
    void onCreated(int moveId, in Bundle extras);
    void onStatusChanged(int moveId, int status, long estMillis);
}

然后我们直接调用 PKMS 的 installPackage 方法

String fileName = Environment.getExternalStorageDirectory() + File.separator + File.separator + "wms.apk";
Uri uri = Uri.fromFile(new File(fileName));
int installFlags = 0;
PackageManager pm = getPackageManager();
try {
     PackageInfo pi = pm.getPackageInfo("com.example.pkmsdemo", PackageManager.GET_UNINSTALLED_PACKAGES);
     if (pi != null) {
        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
     }
} catch (PackageManager.NameNotFoundException e) {
}
MyPakcageInstallObserver observer = new MyPakcageInstallObserver();
pm.installPackage(uri, observer, installFlags, "com.example.wmsdemo");

到这里的时候,还是不够,我们需要在 AndroidManifest 中声明 android:sharedUserId=“android.uid.system” 以及对应的权限

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.DELETE_PACKAGES" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

由于在上面增加了 android:sharedUserId=“android.uid.system” 就需要厂商的签名,需要厂商提供签名文件,而这个厂商的签名属于厂商的机密,这个【platform.x509.pem platform.pem】文件是拿不到的 java -jar signapk.jar platform.x509.pem platform.pem 需要签名的apk 签名之后的 apk

只有拿到签名文件,才能像 MainActivity 的那种方式安装;

运行时权限


Android 在 6.0 引入了动态权限,需要用户在使用到的时候进行授权;常规的动态权限申请,大家直接看开发文档或者百度一下就可以自行实现;我们接下来基于这个运行时权限使用 aspectj 来封装一个权限申请框架;

权限注解

aspectj 是基于注解的注解的方式,首先我们需要定义几个注解,注解如何定义,可以查看我前面的文章 Java中的注解、反射、手写ButterKnife核心实现 关于注解的详细讲解;

/**
 * 权限申请注解
 */
@Target(ElementType.METHOD)  // 方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时
public @interface Permission {

    // 具体申请的权限
    String[] value();

    // 默认的
    int requestCode() default -1;

}

我们还需要另外两个注解,一个是权限取消时的回调注解,一个是权限拒绝时的回调注解;

权限取消注解

/**
 * 权限取消注解
 */
@Target(ElementType.METHOD)  // 方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时
public @interface PermissionCancel {

    int requestCode() default -1;

}

权限拒绝注解

/**
 * 权限拒绝注解
 */
@Target(ElementType.METHOD)  // 方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时
public @interface PermissionDenied {

    int requestCode() default -1;

}

权限申请结果回调

我们还需要一个接口,来回调相关权限申请结果

public interface IPermission {

    void ganted(); // 已经授权

    void cancel(); // 取消权限

    void denied(); // 拒绝权限
}

使用声明的注解

// 申请权限  函数名可以随意些
@Permission(value = Manifest.permission.READ_EXTERNAL_STORAGE, requestCode = 200)
public void testRequest() {
    Toast.makeText(this, "权限申请成功...", Toast.LENGTH_SHORT).show();
}

桥接 Activity

权限的申请,需要 onRequestPermissionsResult 回调中处理请求结果,而这个方法是 Context 的,我们需要通过一个透明的 Activity 桥接一下请求以及回调结果;

public class PermissionActivity extends Activity {

    /** 定义权限处理的标记,接收用户传递进来的 */
    private final static String PARAM_PERMSSION = "param_permission";
    private final static String PARAM_PERMSSION_CODE = "param_permission_code";
    public final static int PARAM_PERMSSION_CODE_DEFAULT = -1;

    /** 真正接收权限存储的变量 */ 
    private String[] permissions;
    private int requestCode;
    
    /** 方便回调的监听,告诉调用者申请结果:已授权,被拒绝,被取消 */
    private static IPermission iPermissionListener;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置为 透明 的 Activity
        setContentView(R.layout.activity_my_permission);

        // 接收传递进来的要申请的权限,READ_EXTERNAL_STORAGE 以这个为例子
        permissions = getIntent().getStringArrayExtra(PARAM_PERMSSION);
        requestCode = getIntent().getIntExtra(PARAM_PERMSSION_CODE, PARAM_PERMSSION_CODE_DEFAULT);

        if (permissions == null && requestCode < 0 && iPermissionListener == null) {
            this.finish();
            return;
        }

        // 能够走到这里,就开始去检查,是否已经授权了
        boolean permissionRequest = PermissionUtils.hasPermissionRequest(this, permissions);
        // 已经授权了,不需要申请,直接回调结果
        if (permissionRequest) {
            // 通过监听接口,告诉外交,已经授权了
            iPermissionListener.ganted();
            this.finish();
            return;
        }

        // 能够走到这里,就证明,还需要去申请权限
        ActivityCompat.requestPermissions(this, permissions, requestCode);
    }

    // 申请的结果
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String[] permissions,
                                           @NonNull int[] grantResults) { 
        // 如果申请三个权限  grantResults.len = 3
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // 返回的结果,需要去验证一下,是否完全成功
        if (PermissionUtils.requestPermissionSuccess(grantResults)) {
            iPermissionListener.ganted(); // 已经授权成功了
            this.finish();
            return;
        }

        // 没有成功
        // 如果用户点击了,拒绝(勾选了"不再提醒") 等操作
        if (!PermissionUtils.shouldShowRequestPermissionRationale(this, permissions)) {
            // 用户拒绝,不再提醒
            iPermissionListener.denied();
            this.finish();
            return;
        }

        // 取消
        iPermissionListener.cancel();
        this.finish();
        return;
    }

    // 让此 Activity 不要有任何动画
    @Override
    public void finish() {
        super.finish();
        overridePendingTransition(0, 0);
    }

    /**
     * 此权限申请专用的 Activity,对外暴露 static
     */
    public static void requestPermissionAction(Context context, String[] permissions,
                                               int requestCode, IPermission iPermissionListener) {
        PermissionActivity.iPermissionListener = iPermissionListener;
        // 启动这个空白的Activity 并接收相关要申请的权限,并发起权限申请
        Intent intent = new Intent(context, PermissionActivity.class);
        // 启动模式
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        Bundle bundle = new Bundle();
        bundle.putInt(PARAM_PERMSSION_CODE, requestCode);
        bundle.putStringArray(PARAM_PERMSSION, permissions);
        intent.putExtras(bundle);
        context.startActivity(intent);
    }

}

注解处理 Aspectj

接下来我们需要通过 Aspectj 来处理相关的注解;

Aspectj 中有两个概念,一个是切点,一个是切面;切点就是我们要切入的地方,切面就是我们从切入的地方,切下来之后的内容;

切点函数

Aspectj 中通过 @Pointcut 注解来标记切点,我们来声明切点函数;

@Aspect
public class PermissionAspect {
    // 通过 @Pointcut 来标记切点函数,传递需要处理的注解,也就是我们前面声明的 Permisson 注解;
    // @Permission == permission
    @Pointcut("execution(@com.example.permission.annotation.Permission * *(..)) && @annotation(permission)")
    public void pointActionMethod(Permission permission) {} // 切点函数
}

切面函数

Aspectj中通过 @Around 注解来标记切面函数,我们来声明切面函数

@Aspect
public class PermissionAspect {

    // 注解中传入的切点函数名必须和声明的一样才能找到
    @Around("pointActionMethod(permission)")
    public void aProceedingJoinPoint(final ProceedingJoinPoint point, Permission permission) throws Throwable {
        // 先定义一个上下文操作创建
        Context context = null;
        // thisObject == null 环境有问题
        final Object thisObject = point.getThis(); 
        // context初始化
        if (thisObject instanceof Context) {
            context = (Context) thisObject;
        } else if (thisObject instanceof Fragment) {
            context = ((Fragment) thisObject).getActivity();
        }

        // 判断是否为null
        if (null == context || permission == null) {
            throw new IllegalAccessException("null == context || permission == null is null");
        }
        final Context finalContext = context;

        // 调用空白的 Activity 申请权限;
        // 通过 Aspectj 拿到了 @Permission(value = Manifest.permission.READ_EXTERNAL_STORAGE, requestCode = 200) 注解,并获取注解上的所有信息;
        PermissionActivity.requestPermissionAction(context, permission.value(), permission.requestCode(), new IPermission() {
            // 已经授权
            @Override
            public void ganted() {
                // 申请成功
                try {
                    // 被 Permission 标记的函数,正常执行下去,不拦截,此时就会执行 testRequest 函数
                    point.proceed();
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }

            @Override
            public void cancel() {
                // 被拒绝
                PermissionUtils.invokeAnnotion(thisObject, PermissionCancel.class);
            }

            @Override
            public void denied() {
                // 被拒绝(不再提醒的)
                PermissionUtils.invokeAnnotion(thisObject, PermissionDenied.class);
            }
        });
    }
}

Aspectj 是通过『动态修改字节码』来实现切面处理;本质就是:把切面函数的具体实现剪切到了注解标记的函数中;

public void testRequest() {
    // 调用 空白的 Activity 申请权限
    MyPermissionActivity.requestPermissionAction(context, permission.value(), permission.requestCode(), new IPermission() {
       // 已经授权
       @Override
       public void ganted() {
           // 申请成功
           try {
               Toast.makeText(this, "权限申请成功...", Toast.LENGTH_SHORT).show();
           } catch (Throwable throwable) {
               throwable.printStackTrace();
           }
       }
       // 省略部分代码
    }                    
}

好了,权限管理就到这里吧

下一章预告


WMS 启动流程分析

欢迎三连


来都来了,点个关注,点个赞吧,你的支持是我最大的动力~~~

【Bug已解决】Context window exceeded / Token limit reached — Claude Code 上下文窗口超限解决方案 Claude Code 长会话中报上下文窗口/Token 超限,本质是对话历史、文件内容、工具结果累积超过 200K 上限。文中给出 /clear、/compact、分批读大文件、限制工具输出、配置 autoCompact 等完整方案。 阅读详情

相关推荐

手把手教你用海康威视相机+DLP4500搭建双目结构光系统(附避坑指南)

本文详细介绍了如何使用海康威视相机和DLP4500搭建双目结构光三维测量系统,涵盖硬件选型、系统搭建、双目标定及三维重建等关键步骤。特别针对预算有限的开发者和实验室团队,提供实用的避坑指南和优化技巧,帮助实现0.02mm的高精度测量。

weixin_42526087的博客 461

PackageManagerService启动详解(七)之扫描系统应用安装目录阶段流程分析

PKMS启动详解(七)之BOOT_PROGRESS_PMS_SYSTEM_SCAN_START阶段流程分析 Android PackageManagerService系列博客目录: PKMS启动详解系列博客概要 PKMS启动详解(一)之整体流程分析 PKMS启动详解(二)之怎么通过packages.xml对已安装应用信息进行持久化管理? PKMS启动详解(三)之BOOT_PROGRESS_PMS_START流程分析 PKMS启动详解(四)之Android包信息体和包解析器(上) PKMS启动详解(五)之

IT先森 4330

支持向量机算法(带你了解原理 实践)

支持向量机作为一种强大的分类算法,在各个领域都取得了显著的成果。其基于统计学习理论的原理使得它能够在高维空间中找到最优分类超平面,并通过核函数处理非线性问题。

2303_79387663的博客 3736

Android程序包管理(1)--PKMS启动过程

一、PKMS启动过程 1、重要文件目录介绍 1.目录: /system/ect/permissions/xxx.xml:加载系统feature /system/ect/permissions/platform.xml:为核心系统进程uid/gid分配默认权限 permission/group:用于建立linux层gid和Android层permission之间的映射关系 assig...

leif 的博客 2234

Multisim实战:从8选1到32选1数据选择器的完整搭建指南(附常见问题解决)

本文提供了一份详尽的Multisim实战指南,手把手教你从基础的8选1数据选择器开始,逐步级联搭建16选1乃至32选1数据选择器。文章深入剖析了级联的核心逻辑、片选方案以及使用译码器的专业方法,并附带了电源连接、输出冲突、信号毛刺等常见问题的诊断与解决技巧,帮助电子工程学生和爱好者扎实掌握数字电路的系统设计与仿真调试。

dd012的博客 729

C#程序突然崩溃怎么办?5分钟学会分析Dump文件(Visual Studio 2022实战)

本文详细介绍了在C#程序崩溃或无响应时,如何捕获并分析Dump文件以快速定位问题。通过Visual Studio 2022实战演示,重点讲解了配置符号服务器、解读调用堆栈与内存状态,以及针对CPU飙高、内存泄漏等典型场景的分析方法,帮助开发者高效进行故障诊断。

docker8compose的博客 474

基于Android T:包管理机制详解(上)

(简称PKMS)是Android系统核心服务之一,和AMS,WMS,IMS并列”Android四大金刚服务“,其管理着整个Android应用的安装更新和卸载等操作。PKMS在我们开发中经常会碰到,了解其底层原理对我们开发也是很有帮助的,比如包体积优化,应用启动优化等。注:本文源码全部基于Android T。

yuhaibing111的博客 1472

【短距离通信】【WiFi】精讲WiFi 6E协议!图解超赞超详细!!!

802.11ax(HE,HighEfficiency) (Wi-Fi 6E):6G频段共有1200MHz的频谱给到WiFi 6E使用,可用于从5.925GHz到7.125GHz。WiFi将可以访问59个20MHz信道,29个40MHz信道14个80MHz信道和7个160MHz信道。这不仅代表可以有很多频道,还可以代表可以解锁更高的数据速率。因为 802.11ax 标准(Wi-Fi 6)也在 2.4GHz 和 5GHz 频段运行,所以 6GHz 频段的 Wi-Fi 将被命名为 Wi-Fi 6E。

风云说通信 2340

android+用户数据+data+放在,Android:利用本地服务器-创建数据库-构建用户表(注册)...

public classUserDataManager {private static final String TAG = "UserDataManager";private static final String DB_NAME = "Register.db";public static final String TABLE_NAME = "Registry";public static fi...

weixin_42134338的博客 603

Debezium报错处理系列之二十八: Expiring 1 record(s) for test-ts-0:120001 ms has passed since batch creation

Debezium报错处理系列之二十八: Expiring 1 record(s) for test-ts-0:120001 ms has passed since batch creation

zhengzaifeidelushang的博客 3290

µC/OS-II---任务就绪表

意思是:将变量OSRdyGrp中最低位为1的位数赋给y,那么,y就是最高优先级任务所在就绪表的行号,那么最高优先级的任务就在OSRdyGrp[y]行中,再根据。

weixin_45880844的博客 1649

如何应对Android面试官 -> PKMS 安装与签名校验

本章主要围绕以上几个知识点进行讲解,最后会手写一个 权限申请框架;

IT_Android的博客 1134

petalinux2022.2启动文件编译配置

petalinux2021之前的版本里,导入目录components/yocto/下的“environment-setup-aarch64-xilinx-linux” 和 “layers/core/oe-init-build-env”的环境,能使用Yocto的devtool工具。(加入下面内容,先petalinux-build下载完成后才能有源码)制作 BOOT.BIN 启动文件:petalinux-package --boot --fsbl --fpga --u-boot --force。

wangjie36的博客 1387

腾讯资深安卓开发者建议:没学完《Android Framework开发揭秘》,不找工作!

想必的重要性对于广大安卓开发者来说已经不言而喻了吧!面试的时候凳子还没坐热,面试官就甩出两个问题:‘’?”,“?”…对于已经完整学完的小伙伴来说,这些问题肯定就像小孩子过家家,但如果你没好好啃完这份《》就抱着侥幸心理去面试,毫不夸张想必早已抠出三室一厅了!然而许多人在初涉时,往往对的重要性认识不足,这种现象就如同他们对的忽视一样普遍。随着学习与实践的深入,终究会意识到的重要性,又不得不回过头来系统地填补这一知识的空白。

Androiddddd的博客 862

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

如何从Android应用深入到Framework?

很多公司的应用开发需要基于模块化、层次化、组件化、控件化来设计架构,它的基础就是建立在Android Framework框架的底层原理之上,学习Framework可以深层次的去解决安卓应用开发时遇到的一些难题,甚至不少公司都有设置专门的Android Framework开发岗位。有的公司的面试可能大部分都是关于Framewoke方面的,尤其是Android Framework中各个组件的原理。第一,不管你去面试哪家公司,Framework是必问项,而Framework使用范围广,无论如何是避不开的;

Eqiqi的博客 878

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

阿里2023全新推出:Android Framework源码手册,知识点全面覆盖|开源PDF

从入行开始,就常常听到身边的人在讨论Framework这方面的问题,过了这么久,有关Framework的讨论愈演愈烈,不仅在工作中能遇到它,现在还成为了一些公司面试的门槛,在面试中10道题,基本上有7,8道是它。但是在现实中真正精通Framework的人少之又少,有些人在简历中写着“精通”二字,但随着面试官的层层追问,一下就会被问的哑口无言。

datian1234的博客 319

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

PKMS权限管理简单分析

拉起应用授权的系统应用原来是在 PackageInstall.apk中,android11后更改到PermissionControll.apk,这里注意看是否google原生的还是其他平台的。android 11及以上源码。主要涉及到的activity为。保存权限到手机的位置。

孙国庆的博客 663

一篇文章看明白 Android PackageManagerService 工作流程

Android - PackageMangerService 分析 概述 PackageManagerService(简称 PKMS),是 Android 系统中核心服务之一,管理着所有跟 package 相关的工作,常见的比如安装、卸载应用。 PackageManagerService 是在 SystemServer 进程中启动的。如不了解 Android 是如何从开机到 Launcher 启...

jeanboy 2万+

Android 支持的系统的share uid

系统支持的sharedUersid

qunimaode的博客 1445

Android权限管理原理(含6.0-4.3)

Android 4.3-5.1 AppOpsManager动态权限管理(官方不成熟的权限管理) AppOpsManager 是Google在Android4.3-Android5.0引入的动态权限管理方式,但是又与Google觉得不成熟,所以在每个发行版的时候,总是会将这个功能给屏蔽掉。国内一些早期版本的权限动态管理的表现类似,这里用CyanogenMod12里面的实现讲述一下,国内的ROM源码...

happylishang的专栏 9756

Android面试题:Handler、Binder、AMS、WMS面试必问题(带答案,万字总结,精心打磨,快收藏)

前言 业内一直有一个说法:技术好的未必底层够硬,但底层扎实的学起来进步如飞。这也是为什么如今的大厂都非常注重对底层原理的考察:除了可以看出面试者的即战力,底层原理更能看出一个开发者的发展潜力。 大家对此应该也深有感受,在面试的过程中,底层原理是无论如何都躲不过去的一关。最典型的就是Framework,很多大厂在招聘中都对此做出了明确的要求: 众所众知,Android的Framework层主要是由WMS、AMS还有View所构成,这三个模块穿插交互在整个Framework中。Binder和Handler更是

Android23333的博客 1427

PKMS源码解析

PKMS指PackageManagerService服务本身以及PackageManagerService服务运作时使用到的各种其他系统服务;是Android系统中的核心服务之一,负责应用程序的安装、卸载以及信息查询等工作;1.解析AndroidManifest.xml文件,解析清单文件中的所有节点信息; 2.扫描.apk文件,安装系统应用、本地应用等; 3.管理本地应用,主要有安装、卸载、应用信息查询等; 客户端通过拿到ApplicationPackageManager对象,通过binder进行跨进程通信

故不积跬步无以至千里 1431

PKMS知识点梳理

参考1:http://blog.youkuaiyun.com/gaugamela/article/details/52637814#comments 参考2:《深入理解Android卷Ⅱ》邓凡平 一、PKMS的启动、main函数 二、构造函数部分 1、PKMS中的Settings ![Setting相关结构](http://img.blog.youkuaiyun.com/2017032317101697

寻箫之音 3401

浅析Android权限机制(一) —— Android的权限机制

第一章 Android的权限机制 Android是基于Linux的系统,其权限访问控制自然离不开Linux的权限访问控制,而在第一章当中,将分成两个部分来剖析Android的权限控制系统。 一. Linux权限机制 Linux的权限访问是由进程(访问者)和文件(被访问者)两部分组成的。其中相当一部分内容参考至APUE[1]。 1.1 Llinux文件权限 我们在Lin...

weixin_30663391的博客 400

基于Android P版本PKMS详解一

[TOC] # 一 修改记录 | 版本 | 修改日期 | 作者 | 修改内容 | | :----| ----------| ----- | ------- | | v1.0 | 2019.05.09 | 初版 | # 二 概述 PackageManagerService (简称 `PKMS`),是 Android 系统中核心服务之一,管理着所有跟 package 相关的工作...

zhang_jun_xiang的博客 1858

PKMS概述

  PKMS和AMS一样是Android系统的核心服务,它主要负责系统中Package的管理,应用程序的安装、卸载、信息查询等工作。PKMS也是由system_server调用PKMS的main函数启动的: // Start the package manager. Slog.i(TAG, "Package Manager"); mPack...

weixin_34088598的博客 562
上一篇: 如何应对Android面试官 -> PKMS 安装与签名校验
下一篇: 如何应对Android面试官 -> WindowManagerService 启动流程分析
老A说
博客等级 码龄14年 1181粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值