深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
//初始化StackSupervisor,该类是Activity启动和调度的核心类
mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
6.AMS 的方法 systemReady
- 在 systemReady 的时候初始化了 deviceIdleController 等对象
- 移除并杀死了那些不该在 AMS 之前启动的进程
- 执行了参数传入的回调函数
- 启动了 Launcer 界面和 SystemUI
- 启动那些 persistent 配置为 1 的进程。
总结:AMS 服务启动主要分为几个步骤 小米视频增加组内自动化测试
- 创建了 SystemServer 进程的运行环境,包括一个 ActivityThread 主线程,一个和系统进程相关的 Context 对象。
- 调用 AMS 的构造方法和 start 方法,对 AMS 必要的内容进行初始化
- 将函数 AMS 注册到 ServiceManager 中,同时对 systemServer 进程也创建了一个 ProcessRecord 对象,并设置 Context 的 appliation 为 framework-res 的 application 对象
- 将 settingsProvider 加载到系统进程 systemServer 中
- 调用 systemReady 方法做一些启动前的就绪工作,并启动了 HomeActivity 和 SystemUI
AMS启动流程
(1)main
/frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
(2)run
/frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
try {
…
// 创建Looper
Looper.prepareMainLooper();
// 加载libandroid_servers.so
System.loadLibrary(“android_servers”);
// 创建系统的 Context:ContextImpl.createSystemContext(new ActivityThread())
createSystemContext();
// 创建 SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
…
}
…
try {
//启动引导服务,ActivityManagerService、ActivityTaskManagerService、PackageManagerService、PowerManagerService、DisplayManagerService 等
startBootstrapServices();
//启动核心服务,BatteryService、UsageStatusService 等
startCoreServices();
//启动其他服务,InputManagerService、WindowManagerService、CameraService、AlarmManagerService 等
startOtherServices();
…
}
…
// 开启消息循环
Looper.loop();
}
(3)startBootstrapServices
/frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices() {
…
Installer installer = mSystemServiceManager.startService(Installer.class);
…
//启动 ATMS
ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();
//启动 AMS,并注入 ATMS
mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
//注入 mSystemServiceManager 和 installer
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
…
//启动 PMS
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
…
mActivityManagerService.initPowerManagement();
…
mActivityManagerService.setSystemProcess();
}
(4)AMS.Lifecycle
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
private static ActivityTaskManagerService sAtm;
public Lifecycle(Context context) {//被 SystemServiceManager 的 startService() 方法调用
super(context);
mService = new ActivityManagerService(context, sAtm);
}
public static ActivityManagerService startService(SystemServiceManager ssm, ActivityTaskManagerService atm) {
sAtm = atm;
return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
}
public void onStart() {
mService.start(); //调用 AMS 的 start() 方法
}
…
public ActivityManagerService getService() {
return mService;
}
}
(5)startService
public T startService(Class serviceClass) {
try {
final String name = serviceClass.getName();
…
final T service;
try { //通过反射调用 serviceClass 的构造方法 创建 Lifecycle 对象
Constructor constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
}
…
startService(service);
return service;
}
…
}
public void startService(SystemService service) {
mServices.add(service); //mServices: ArrayList
…
try {
service.onStart(); //调用 Lifecycle 的 onStart 方法
}
…
}
注意:startService() 方法中调用了 Lifecycle 的 onStart() 方法,进一步调用 AMS 的 start() 方法初始化(下文还会介绍)。
AMS 初始化
初始化过程如下:
(1)AMS 的构造方法
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
…
mInjector = new Injector();
mContext = systemContext;
…
mSystemThread = ActivityThread.currentActivityThread();
mUiContext = mSystemThread.getSystemUiContext();
…
mHandlerThread = new ServiceThread(TAG, THREAD_PRIORITY_FOREGROUND, false);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = mInjector.getUiHandler(this);
…
mProcStartHandlerThread = new ServiceThread(TAG + “:procStart”, THREAD_PRIORITY_FOREGROUND, false);
mProcStartHandlerThread.start();
mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
…
final ActiveUids activeUids = new ActiveUids(this, true);
mPlatformCompat = (PlatformCompat) ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
mProcessList.init(this, activeUids, mPlatformCompat);
…
mServices = new ActiveServices(this); //用于启动 Service
mProviderMap = new ProviderMap(this); //存储 ContentProvider
…
mUserController = new UserController(this);
mPendingIntentController = new PendingIntentController(mHandlerThread.getLooper(), mUserController);
…
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
mActivityTaskManager = atm;
//进一步初始化 ATMS
mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController, DisplayThread.get().getLooper());
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
…
}
(2)start
start() 方法被 Lifecycle 的 onStart() 方法调用,onStart() 方法又被 SystemServiceManager 的 startService() 方法调用。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private void start() {
…
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
mActivityTaskManager.onActivityManagerInternalAdded();
mUgmInternal.onActivityManagerInternalAdded();
mPendingIntentController.onActivityManagerInternalAdded();
…
}
(3)initPowerManagement、setSystemProcess
在 SystemServer 的 startBootstrapServices() 方法中,调用了 AMS 的 initPowerManagement() 和 setSystemProcess() 方法。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void initPowerManagement() {
mActivityTaskManager.onInitPowerManagement();
mBatteryStatsService.initPowerManagement();
mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
}
public void setSystemProcess() {
try {
…
synchronized (this) {
ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName, false, 0, new HostingRecord(“system”));
app.setPersistent(true);
app.pid = MY_PID;
app.getWindowProcessController().setPid(MY_PID);
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
mPidsSelfLocked.put(app);
mProcessList.updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
}
}
…
}
(4)setUsageStatsManager
在 SystemServer 的 startCoreServices() 方法中,调用了 AMS 的 setUsageStatsManager() 方法。
/frameworks/base/services/java/com/android/server/SystemServer.java
private void startCoreServices() {
…
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(LocalServices.getService(UsageStatsManagerInternal.class));
…
}
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
mUsageStatsService = usageStatsManager;
mActivityTaskManager.setUsageStatsManager(usageStatsManager);
}
(5)installSystemProviders、setWindowManager、systemReady
在 SystemServer 的 startOtherServices() 方法中,调用了 AMS 的 installSystemProviders()、setWindowManager() 和 systemReady() 方法。
/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
…
WindowManagerService wm = null;
…
try {
…
mActivityManagerService.installSystemProviders(); //1
…
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
…
mActivityManagerService.setWindowManager(wm); //2
…
}
…
mActivityManagerService.systemReady(() -> { //3
…
mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
…
try {
mActivityManagerService.startObservingNativeCrashes();
}
…
try {
startSystemUi(context, windowManagerF);
}
…
mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
…
}, BOOT_TIMINGS_TRACE_LOG);
}
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final void installSystemProviders() {
List providers;
synchronized (this) {
ProcessRecord app = mProcessList.mProcessNames.get(“system”, SYSTEM_UID);
providers = generateApplicationProvidersLocked(app);
…
}
if (providers != null) {
mSystemThread.installSystemProviders(providers);
}
…
mConstants.start(mContext.getContentResolver());
mCoreSettingsObserver = new CoreSettingsObserver(this);
mActivityTaskManager.installSystemProviders();
…
}
public void setWindowManager(WindowManagerService wm) {
synchronized (this) {
mWindowManager = wm;
mActivityTaskManager.setWindowManager(wm);
}
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
//添加 AMS 服务,方便跨进程调用
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
…
synchronized(this) {
…
mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class);
mActivityTaskManager.onSystemReady();
mUserController.onSystemReady();
mAppOpsService.systemReady();
mSystemReady = true;
}
…
}
已通过 ServiceManager.addService() 将 Context.ACTIVITY_SERVICE 与 AMS 绑定,因此在其他进程中可以通过如下方式获取 AMS。
IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
IActivityManager am = IActivityManager.Stub.asInterface(b);
PMS篇
PackageManagerService(简称 PMS),是 Android 系统核心服务之一,处理包管理相关的工作,常见的比如安装、卸载应用等。PMS是系统服务,那么应用层肯定有个PackageManager作为binder call client端来供使用,但是这里要注意,PackageManager是个抽象类,一般使用的是它的实现类:ApplicationPackageManager。因此PackageManager功能的具体实现还是ApplicationPackageManager这个实现类
PMS的功能
1、安装、卸载应用
2、查询permission相关信息
3、查询Application相关信息(application、activity、receiver、service、provider及相应属性等)
4、查询已安装应用
5、增加、删除permission
6、清除用户数据、缓存、代码等
接口的讲解
1.PackaeManager.java ----------------------> ApplicationPackageManager.java------------------------------->PackageManagerService.java
- queryIntentActivities(intent, PackageManager.MATCH_ALL): 查询包含这个Intent的Activity
- resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) : 查询是否有满足这个Intent的Activity
- clearPackagePreferredActivities() : 清除默认的修改
- addPreferredActivity() : 修改默认的配置
- if (r.match > bestMatch) bestMatch = r.match;***
- replacePreferredActivity() : 替换Intent 匹配相同的Activity
- getPackageUid(String packageName) : 获取相应包的UID
- getPermissionInfo(String packageName, int flags (大部分默认为0)) : 通过包名获取权限
- getApplicationInfo(String packageName,int flags) : 检索出一个应用程序的所有信息
- getActivityInfo(ComponentName component,int flags) : 检索出一个特定的Activity类的所有信息`
- getPackageInfo(String packageName, int flags) : 包名获取该包名对应的应用程序的PackageInfo对象
- getInstalledPackages(int flags(一般传值为0)) : 返回设备上所有已经安装的应用程序集合
入参params flags 附加选项的标志位,你可以理解为筛选条件,可以使用的标志位为:
GET_ACTIVITIES :(packageInfo的标志)表示 返回包(packageInfo)中包含的所有Activity信息
GET_GIDS :(packageInfo的标志)表示 返回关联的GID(groupId)
GET_CONFIGURATIONS :(packageInfo的标志)表示 配置选项信息
GET_INSTRUMENTATION :(PackageInfo的标志)表示 是否使用了instrumentation
GET_PERMISSIONS :(PackageInfo的标志)表示 是否使用了permissions
GET_PROVIDERS :(PackageInfo的标志)表示 是否使用了providers
GET_RECEIVERS :(PackageInfo的标志)表示 是否使用了recevier
GET_SERVICES :(PackageInfo的标志)表示 是否使用了service
GET_SIGNATURES :(PackageInf的标志) 表示是否使用包的签名信息
GET_UNINSTALLED_PACKAGES:参数标志位,表示检索出所有有数据的目录的应用程序(主要是卸载的)的信息
安装过程
1.准备工作
前面说到 APK 的信息会提交给 PMS 进行安装的一系列工作,具体是通过 PackageHandler 发送消息来驱动 APK 的复制和安装,其时序图如下:
上相过程中有几点需要说明:
1、在 installStage 方法中创建了 InstallParams 对象,它对应于包的安装数据,并创建 INIT_COPY 消息并发送给 PackageHandler 进行处理;
2、PackageHandler 在处理 INIT_COPY 消息时,会先判断是否绑定了 DefaultContainerService ,这是用于检查和赋值可移动文件的服务,比较耗时,所以和 PMS 并没有运行在同一个进程中,它们之间通过 IMediaContainerService 进行 IPC 通信,没有绑定则会进行绑定,之后
DefaultContainerConnection 同样是定义在 PMS 中,执行链路如下:
PackageHandler -> doHandleMessage(INIT_COPY)
-> connectToService()
{
连接成功
mBound = true;
}
-> bindServiceAsUser()
-> DefaultContainerConnection
-> onServiceConnected()
-> sendMessage(MCS_BOUND)
3、发送 MCS_BOUND 消息时,根据发送的 Message 是否带 Object 分为两种,如下所示:
void doHandleMessage(Message msg) {
switch (msg.what) {
case INIT_COPY: {
…
//mBound用于标识是否绑定了服务,默认值为false
if (!mBound) {
…
if (!connectToService()) {
// 绑定 DefaultContainerConnection 成功之后会发送
// mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, Object));
…
//绑定服务失败则return
return;
} else {
//绑定服务成功,将请求添加到ArrayList类型的mPendingInstalls中,等待处理
mPendingInstalls.add(idx, params);
}
} else {
//已经绑定服务
mHandler.sendEmptyMessage(MCS_BOUND);
}
break;
}
…
}
}
}
4、 MCS_BOUND 消息的处理:
case MCS_BOUND: {
if (DEBUG_INSTALL) Slog.i(TAG, “mcs_bound”);
if (msg.obj != null) {
…
}
if (mContainerService == null) {//1
…
} elseif (mPendingInstalls.size() > 0) {//2
HandlerParams params = mPendingInstalls.get(0);//3
if (params != null) {
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, “queueInstall”,
System.identityHashCode(params));
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, “startCopy”);
if (params.startCopy()) {//4
if (DEBUG_SD_INSTALL) Log.i(TAG,
“Checking for more work or unbind…”);
//如果APK安装成功,删除本次安装请求
if (mPendingInstalls.size() > 0) {
mPendingInstalls.remove(0);
}
if (mPendingInstalls.size() == 0) {
if (mBound) {
//如果没有安装请求了,发送解绑服务的请求
if (DEBUG_SD_INSTALL) Log.i(TAG,
“Posting delayed MCS_UNBIND”);
removeMessages(MCS_UNBIND);
Message ubmsg = obtainMessage(MCS_UNBIND);
sendMessageDelayed(ubmsg, 10000);
}
} else {
if (DEBUG_SD_INSTALL) Log.i(TAG,
“Posting MCS_BOUND for next work”);
//如果还有其他的安装请求,接着发送MCS_BOUND消息继续处理剩余的安装请求
mHandler.sendEmptyMessage(MCS_BOUND);
}
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}else {
Slog.w(TAG, “Empty queue”);
}
break;
}
2.复制APK
2.1 复制过程时序图
HandlerParams 是 PMS 中的抽象类,它的实现类为 PMS 的内部类 InstallParams。HandlerParams 的 startCopy 方法如下所示:
2.2 复制过程的源码分析
PackageManagerService.java#HandlerParams
final boolean startCopy() {
boolean res;
try {
if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
//startCopy方法尝试的次数,超过了4次,就放弃这个安装请求
if (++mRetries > MAX_RETRIES) {
Slog.w(TAG, “Failed to invoke remote methods on default container service. Giving up”);
//MCS_GIVE_UP类型消息,将本次安装请求从安装请求队列mPendingInstalls中移除掉
mHandler.sendEmptyMessage(MCS_GIVE_UP);
handleServiceError();
returnfalse;
} else {
handleStartCopy(); // 注释①
res = true;
}
} catch (RemoteException e) {
if (DEBUG_INSTALL) Slog.i(TAG, “Posting install MCS_RECONNECT”);
mHandler.sendEmptyMessage(MCS_RECONNECT);
res = false;
}
handleReturnCode();
return res;
}
在 注释① 处调用抽象方法 handleStartCopy ,具体实现在 InstallParams 中,如下所示:
PackageManagerService.java#InstallParams
public void handleStartCopy() throws RemoteException {
…
//确定APK的安装位置。onSd:安装到SD卡, onInt:内部存储即Data分区,ephemeral:安装到临时存储(Instant Apps安装)
finalboolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
finalboolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
finalboolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
PackageInfoLite pkgLite = null;
if (onInt && onSd) {
// APK不能同时安装在SD卡和Data分区
Slog.w(TAG, “Conflicting flags specified for installing on both internal and external”);
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
//安装标志冲突,Instant Apps不能安装到SD卡中
} elseif (onSd && ephemeral) {
Slog.w(TAG, “Conflicting flags specified for installing ephemeral on external”);
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
} else {
//获取APK的少量的信息
pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
packageAbiOverride);
if (DEBUG_EPHEMERAL && ephemeral) {
Slog.v(TAG, "pkgLite for install: " + pkgLite);
}
…
if (ret == PackageManager.INSTALL_SUCCEEDED) {
//判断安装的位置
int loc = pkgLite.recommendedInstallLocation;
if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
} elseif (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
}
…
}else{
loc = installLocationPolicy(pkgLite); // 注释①
…
}
}
//根据InstallParams创建InstallArgs对象
final InstallArgs args = createInstallArgs(this); // 注释②
mArgs = args;
if (ret == PackageManager.INSTALL_SUCCEEDED) {
…
if (!origin.existing && requiredUid != -1
&& isVerificationEnabled(
verifierUser.getIdentifier(), installFlags, installerUid)) {
…
} else{
ret = args.copyApk(mContainerService, true); // 注释③
}
}
mRet = ret;
}
- 注释① 处确定了 APK 的安装位置。
- 注释②处创建 InstallArgs 对象,此对象是一个抽象类,定义了 APK 的复制和重命名APK等安装逻辑,在 Android 8.x 及之前的版本中有三个子类:FileInstallArgs、AsecInstallArgs、MoveInstallArgs。其中 FileInstallArgs 用于处理安装到非ASEC的存储空间的APK,即内部存储空间(Data分区);AsecInstallArgs 用于处理安装到ASEC(mnt/asec)即SD卡中的APK;MoveInstallArgs 用于处理已安装APK的移动的逻辑;但在 Android 9.x 之后已经去掉了 AsecInstallArgs ,
- 注释③ 处调用 InstallArgs 的 copyApk 方法,这里以 FileInstallArgs 的实现为例,内部会调用 FileInstallArgs 的 doCopyApk 方法:
private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
…
try {
finalboolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
//创建临时文件存储目录
final File tempDir =
mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); // 注释①
codeFile = tempDir;
resourceFile = tempDir;
} catch (IOException e) {
Slog.w(TAG, "Failed to create copy file: " + e);
return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}
…
int ret = PackageManager.INSTALL_SUCCEEDED;
ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); // 注释②
…
return ret;
}
- 注释① 处用于创建临时存储目录,比如 /data/app/vmdl18300388.tmp,其中 18300388 是安装的 sessionId;
- 注释②处通过 IMediaContainerService 跨进程调用 DefaultContainerService 的 copyPackage 方法,这个方法会在 DefaultContainerService 所在的进程中将 APK 复制到临时存储目录,比如 /data/app/vmdl18300388.tmp/base.apk ,至此 APK 的复制工作结束。
3.APK的安装
3.1 APK安装时序图
在上述 APK 的赋值调用链的过程中,在 HandlerParams 的 startCopy 方法中,会调用 handleReturnCode 方法,时序图如下:
3.2 安装源码分析
PackageManagerService#handleReturnCode:
void handleReturnCode() {
if (mArgs != null) {
processPendingInstall(mArgs, mRet);
}
}
private void processPendingInstall(final InstallArgs args, final int currentStatus) {
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
PackageInstalledInfo res = new PackageInstalledInfo();
res.setReturnCode(currentStatus);
res.uid = -1;
res.pkg = null;
res.removedInfo = null;
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
//安装前处理
args.doPreInstall(res.returnCode); //注释①
synchronized (mInstallLock) {
installPackageTracedLI(args, res); //注释②
}
//安装后收尾
args.doPostInstall(res.returnCode, res.uid); //注释③
}
…
// 安装结束发送消息
Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); // 注释⑤
mHandler.sendMessage(msg);
}
});
}
- 注释① 处检查APK的状态,在安装前确保安装环境的可靠,如果不可靠会清除复制的APK文件,注释③ 处会检测是否安装成功,失败则删除安装相关的目录和文件。安装完成之后在 注释⑤ 处会发送 POST_INSALL 消息通知已安装完成,此处稍后会说明。
- 注释② 处的 installPackageTracedLI 会调用 PMS 的 installPackageLI 方法:
PackageManagerService.java#installPackageLI:
private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
…
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
pp.setDisplayMetrics(mMetrics);
pp.setCallback(mPackageParserCallback);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, “parsePackage”);
final PackageParser.Package pkg;
try {
//解析APK
pkg = pp.parsePackage(tmpPackageFile, parseFlags); //注释①
} catch (PackageParserException e) {
res.setError(“Failed parse during installPackageLI”, e);
return;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
…
pp = null;
String oldCodePath = null;
boolean systemApp = false;
synchronized (mPackages) {
// 检查APK是否存在
if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
String oldName = mSettings.getRenamedPackageLPr(pkgName);//获取没被改名前的包名
if (pkg.mOriginalPackages != null
&& pkg.mOriginalPackages.contains(oldName)
&& mPackages.containsKey(oldName)) {
pkg.setPackageName(oldName); //注释②
pkgName = pkg.packageName;
replace = true;//设置标志位表示是替换安装
if (DEBUG_INSTALL) Slog.d(TAG, “Replacing existing renamed package: oldName=”
- oldName + " pkgName=" + pkgName);
}
…
}
PackageSetting ps = mSettings.mPackages.get(pkgName);
//查看Settings中是否存有要安装的APK的信息,如果有就获取签名信息
if (ps != null) { //注释③
if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
PackageSetting signatureCheckPs = ps;
if (pkg.applicationInfo.isStaticSharedLibrary()) {
SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
if (libraryEntry != null) {
signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
}
}
//检查签名的正确性
if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " - pkg.packageName + " upgrade keys do not match the "
- “previously installed version”);
return;
}
}
…
}
int N = pkg.permissions.size();
for (int i = N-1; i >= 0; i–) {
//遍历每个权限,对权限进行处理
PackageParser.Permission perm = pkg.permissions.get(i);
BasePermission bp = mSettings.mPermissions.get(perm.info.name);
}
}
}
if (systemApp) {
if (onExternal) {
//系统APP不能在SD卡上替换安装
res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
“Cannot install updates to system apps on sdcard”);
return;
} elseif (instantApp) {
//系统APP不能被Instant App替换
res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
“Cannot update a system app with an instant app”);
return;
}
}
…
//重命名临时文件
if (!args.doRename(res.returnCode, pkg, oldCodePath)) { //注释④
res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, “Failed rename”);
return;
}
startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
“installPackageLI”)) {
if (replace) { //注释⑤
//替换安装
…
replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
installerPackageName, res, args.installReason);
} else {
//安装新的APK
installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
args.user, installerPackageName, volumeUuid, res, args.installReason);
}
}
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
//更新应用程序所属的用户
res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
ps.setUpdateAvailable(false/updateAvailable/);
}
…
}
}
这里需要说明几点:
1、注释③处,会先检测 Settings 中保存有要安装的 APK 信息,则说明安装该 APK ,因此需要检验APK 的签名信息,确保安全的进行替换。
2、注释④处,会对临时文件重新命名,例如 /data/app/vmdl18300388.tmp/base.apk,重命名为 /data/app/包名-oONlnRRPYyleU63AveqbYA==/base.apk。新的包名后面带上的一串字母和数字的混合字符串,是使用MD5的方式对随机生成的16个字符进行加密之后的产物。
3、注释⑤处,根据 replace 来做区分,如果是替换安装就会调用replacePackageLIF方法,其方法内部还会对系统APP和非系统APP进行区分处理,如果是新安装APK会调用installNewPackageLIF方法
PackageManagerService.java#installNewPackageLIF:
private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
PackageInstalledInfo res, int installReason) {
…
try {
//扫描APK
PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
System.currentTimeMillis(), user);
//更新Settings信息
updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
//安装成功后,为新安装的应用程序准备数据
prepareAppDataAfterInstallLIF(newPackage);
} else {
//安装失败则删除APK
deletePackageLIF(pkgName, UserHandle.ALL, false, null,
PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
}
} catch (PackageManagerException e) {
res.setError("Package couldn’t be installed in " + pkg.codePath, e);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
4.发送消息
在上面 processPendingInstall 方法的源码分析中,在 注释⑤ 处会发送 POST_INSTALL 消息通知安装完成,那么接下来就来具体看一看在 PackageHandler 中是怎么处理这个消息的。
class PackageHandler extends Handler {
void doHandleMessage(Message msg) {
switch (msg.what) {
… …
case POST_INSTALL: {
… …
handlePackagePostInstall();
… …
break;
}
}
}
}
private void handlePackagePostInstall(…){
// 如果已经成功的安装了应用,在发送广播之前先授予一些必要的权限
grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(),
args.installGrantPermissions);
// 安装完成之后发送"ACTION_PACKAGE_ADDED"广播
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
packageName, extras, null, null, firstUsers);
// 如果是升级更新安装,还会发送ACTION_PACKAGE_REPLACED和ACTION_MY_PACKAGE_REPLACED广播
// 这两个广播不同之处在于PACKAGE_REPLACE将携带一个extra信息
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
packageName, extras, null, null, updateUsers);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
null, null, packageName, null, updateUsers);
// 执行gc操作
Runtime.getRuntime().gc();
// 调用FileInstallArgs的doPostDeleteLI进行资源清理
res.removedInfo.args.doPostDeleteLI(true);
// 回调onPackageInstalled方法
installObserver.onPackageInstalled(res.name, res.returnCode,
res.returnMsg, extras);
}
以上为主要的方法摘要,具体可总结为:
1、第一步:这里主要是先将安装信息从安装列列表中移除,这个也是前面在processPendingInstall中添加的
2、第二步:安装成功后,获取运行时权限
3、第三步:获取权限后,发送ACTION_PACKAGE_ADDED广播,告诉Laucher之流,更新icon
4、第四步:如果是升级更新则在发送两条广播
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
a信息
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
packageName, extras, null, null, updateUsers);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
null, null, packageName, null, updateUsers);
// 执行gc操作
Runtime.getRuntime().gc();
// 调用FileInstallArgs的doPostDeleteLI进行资源清理
res.removedInfo.args.doPostDeleteLI(true);
// 回调onPackageInstalled方法
installObserver.onPackageInstalled(res.name, res.returnCode,
res.returnMsg, extras);
}
以上为主要的方法摘要,具体可总结为:
1、第一步:这里主要是先将安装信息从安装列列表中移除,这个也是前面在processPendingInstall中添加的
2、第二步:安装成功后,获取运行时权限
3、第三步:获取权限后,发送ACTION_PACKAGE_ADDED广播,告诉Laucher之流,更新icon
4、第四步:如果是升级更新则在发送两条广播
[外链图片转存中…(img-jZtfD8z2-1715199204820)]
[外链图片转存中…(img-bNhznaHk-1715199204820)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!