Framework底层服务,AMS|PMS|WMS原理分析
Posted 嘴巴吃糖了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Framework底层服务,AMS|PMS|WMS原理分析相关的知识,希望对你有一定的参考价值。
作者:码农的地中海
链接:https://www.jianshu.com/p/657d4c0c9eda
前言
Framework API: Activity Manager/Window Manager/Content Providers/View System/Notification Manager/Package Manager/Telephony Manager/Resource Manager…
其实所谓的AMS,PMS,以及WMS等都是运行在system_server这个进程中的线程。
**Framwork 中的主流服务:**ActivityManagerService、PackageManagerService、WindowManagerService、AlarmManagerService、JobSchedulerService、ResourceManagerService、InputManagerService 等
AMS篇
AMS是系统的引导服务,应用进程的启动、切换和调度、四大组件的启动和管理都需要AMS的支持。
AMS作用
- 统一调度所有应用程序的Activity的生命周期
- 启动或杀死应用程序的进程
- 启动并调度Service的生命周期
- 注册BroadcastReceiver,并接收和分发Broadcast
- 启动并发布ContentProvider
- 调度task
- 处理应用程序的Crash
- 查询系统当前运行状态
AMS启动过程
1.SystemServer.java的main()
public static void main(String[] args)
new SystemServer().run();
2.SystemServer.java的run()
private void run()
System.loadLibrary("android_servers");//1
...
mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
try
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();//3 ---------------->引导服务
startCoreServices();//4 ---------------->核心服务
startOtherServices();//5 ---------------->其他服务
3.SystemServer.java 的startBootstrapServices()
private void startBootstrapServices()
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService();
我们知道 SystemServiceManager 的 startService 方法最终会返回 Lifecycle 类型的对象,紧接着又调用了 Lifecycle 的 getService 方法,这个方法会返回 AMS 类型的 mService 对象
mActivityManagerService.setSystemProcess();
……
mActivityManagerService.installSystemProviders();
……
mActivityManagerService.systemReady(new Runnable()
@Override public void run()
Slog.i(TAG, "Making services ready");
mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY);
try mActivityManagerService.startObservingNativeCrashes();
4.Lifecycle 类的介绍
public static final class Lifecycle extends SystemService
private final ActivityManagerService mService;
public Lifecycle(Context context)
super(context);
mService = new ActivityManagerService(context);
@Override
public void onStart()
mService.start();
*
@Override
public void onCleanupUser(int userId)
mService.mBatteryStatsService.onCleanupUser(userId);
public ActivityManagerService getService()
return mService;
*
5.AMS的构造方法
public ActivityManagerService(Context systemContext) `
//获得系统的ActivityThread
mSystemThread = ActivityThread.currentActivityThread();
//创建一个HandlerThread用来处理AMS接收的命令
mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = new UiHandler();
//初始化广播的队列
mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
//初始化Service相关的容器
mServices = new ActiveServices(this);
//初始化Provider相关的Map,里面保存了注册的ContentProvider
mProviderMap = new ProviderMap(this);```
//初始化并创建data/system/目录
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
//初始化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 extends SystemService> T startService(Class<T> serviceClass)
try
final String name = serviceClass.getName();
...
final T service;
try //通过反射调用 serviceClass 的构造方法 创建 Lifecycle 对象
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
...
startService(service);
return service;
...
public void startService(SystemService service)
mServices.add(service); //mServices: ArrayList<SystemService>
...
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<ProviderInfo> 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、第四步:如果是升级更新则在发送两条广播
- ACTION_PACKAGE_REPLACED:一个新版本的应用安装到设备上,替换换之前已经存在的版本
- ACTION_MY_PACKAGE_REPLACED:应用的新版本替换旧版本被安装,只发给被更新的应用自己
5、第五步:如果安装包中设置了PRIVATE_FLAG_FORWARD_LOCK或者被要求安装在SD卡上,则调用sendResourcesChangedBroadcast方法来发送一个资源更改的广播
6、第六步:如果该应用是一个浏览器,则要清除浏览器设置,重新检查浏览器设置
7、第七步:强制调用gc,出发JVM进行垃圾回收操作
8、第八步:删除旧的安装信息
9、回调回调 IPackageInstallObserver2 的 packageInstalled 方法。告诉 PackageInstaller 安装结果。从而实现了安装回调到UI层
5.安装总结
上述几部分大致说明 PMS 处理 APK 的主要步骤,可总结如下:
1、当 PackageInstaller 将 APK 的信息提交给 PMS 处理,PMS 会通过向 PackageHandler 发送消息来驱动 APK 的复制和安装工作
2、PMS 发送 INIT_COPY 和 MCS_BOUND 类型的消息,控制 PackageHandler 来绑定 DefaultContainerService 来完成 APK 的复制等工作
3、复制 APK 完成之后,则开始进行安装 APK 的流程,包括安装前的检查、安装 APK 和安装后的收尾工作。
WMS篇
WindowManagerService服务(WMS)的实现是相当复杂的,毕竟它要管理的整个系统所有窗口的UI,而在任何一个系统中,窗口管理子系统都是极其复杂的。而WMS就是管理整个系统的窗口的。
WMS功能
- 窗口管理:负责启动、添加、删除窗口,管理窗口大小、层级,核心成员有:WindowContainer、RootWindowContainer、* DisplayContent、TaskStack、Task、AppWindowToken、WindowState;
- 窗口动画:由其子系统 WindowAnimator 管理;
- 输入系统中转站:通过对窗口的触摸从而产生触摸事件,由 InputMethodService(IMS)对触摸事件进行处理,它会寻找一个最合适的窗口处理触摸反馈信息;
- Surface 管理:为每个窗口分配一块 Surface,用于绘制要显示的内容。
WMS创建过程中线程关系
WMS 创建过程中涉及到的类主要有 SystemServer、WindowManagerService(WMS)、WindowManagerPolicy(WMP),它们都在 system_server 进程中运行,但是会在不同线程中运行,如下所示。
WMS启动流程
(1)main
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)startOtherServices
/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices()
...
WindowManagerService wm = null;
...
InputManagerService inputManager = null;
...
try
...
inputManager = new InputManagerService(context);
...
//PhoneWindowManager 是 WMP 的实现类
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager, false, DUMP_FLAG_PRIORITY_CRITICAL);
...
mActivityManagerService.setWindowManager(wm);
...
wm.onInitReady(); //initPolicy
...
//wm 的 mInputManagerCallback 属性在定义时就被初始化
inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
inputManager.start();
...
...
try
wm.displayReady(); //初始化屏幕信息
...
try
wm.systemReady(); //通知 WMS 系统的初始化完成
...
final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
...
注意:在 WindowManagerService.main() 中,传入了 InputManagerService、PhoneWindowManager(WindowManagerPolicy 的实现类)、ActivityTaskManagerService(简称 ATMS)
通过 ServiceManager.addService() 将 Context.WINDOW_SERVICE 与 WMS 绑定,因此在其他进程中可以通过如下方式获取 WMS。
IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
IWindowManager wm = IWindowManager.Stub.asInterface(b);
(3)main
public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs,
final boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm)
return main(context, im, showBootMsgs, onlyCore, policy, atm, SurfaceControl.Transaction::new);
public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs,
final boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm, TransactionFactory transactionFactory)
//在 android.display 线程中创建 WMS(此时 system_server 线程阻塞)
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy, atm, transactionFactory), 0);
return sInstance;
WMS 初始化
本节主要研究 WMS 在初始化时做的工作。
(1)构造函数
/frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
private WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, boolean onlyCore,
WindowManagerPolicy policy, ActivityTaskManagerService atm, TransactionFactory transactionFactory)
...
mAtmService = atm;
mContext = context;
...
mInputManager = inputManager;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
...
mPolicy = policy;
//动画管理
mAnimator = new WindowAnimator(this);
//根容器,其子容器是 DisplayContent
mRoot = new RootWindowContainer(this);
mWindowPlacerLocked = new WindowSurfacePlacer(this);
...
//mPolicy 是 PhoneWindowManager 对象,WindowManagerPolicy 的实现类
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
...
//DM
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
//PM
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
//AMS
mActivityManager = ActivityManager.getService();
//ATMS
mActivityTaskManager = ActivityTaskManager.getService();
//ActivityManagerInternal
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
//ActivityTaskManagerInternal
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
...
//PackageManagerInternal
mPmInternal = LocalServices.getService(PackageManagerInternal.class);
//添加本地服务
LocalServices.addService(WindowManagerInternal.class, new LocalService());
LocalService 是 WMS 的内部类,也是 WindowManagerInternal 的实现类。
(2)初始化 WMP
public void onInitReady()
//初始化 WMP
initPolicy();
...
//打开 Surface 事务:SurfaceControl.openTransaction()
openSurfaceTransaction();
...
private void initPolicy()
//在 android.ui 线程中执行
UiThread.getHandler().runWithScissors(new Runnable()
@Override
public void run()
WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
, 0);
(3)初始化 Display
public void displayReady()
synchronized (mGlobalLock)
if (mMaxUiWidth > 0)
mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
final boolean changed = applyForcedPropertiesForDefaultDisplay();
mAnimator.ready();
...
...
updateCircularDisplayMaskIfNeeded();
(4)通知系统 WMS 初始化完成
public void systemReady()
mSystemReady = true;
mPolicy.systemReady();
mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
mTaskSnapshotController.systemReady();
...
UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings);
UiThread.getHandler().post(mSettingsObserver::updatePointerLocation);
...
总结
服务端
- AMS 主要用于管理所有应用程序的Activity
- WMS 管理各个窗口,隐藏,显示等
- PMS 用来管理跟踪所有应用APK,安装,解析,控制权限等.
- 还有用来处理触摸消息的两个类KeyInputQueue和InputDispatchThread,一个用来读消息,一个用来分发消息.。
客户端
- 主要包括ActivityThread,Activity,DecodeView及父类View,PhoneWindow,ViewRootImpl及内部类等
- ActivityThread主要用来和AMS通讯的客户端,Activity是我们编写应用比较熟悉的类。
这里只是简单的认识和归纳总结一下,非常感谢以上博主的贡献。后期我会深入了解Android系统的源码,然后专开一个专栏来详细介绍PMS、AMS、WMS。
技术资料提供:Frame Work源码解析手册
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
一、架构师筑基必备技能
1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……
二、Android百大框架源码解析
1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程
三、Android性能优化实战解析
- 腾讯Bugly:对字符串匹配算法的一点理解
- 爱奇艺:安卓APP崩溃捕获方案——xCrash
- 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
- 百度APP技术:Android H5首屏优化实践
- 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
- 携程:从智行 Android 项目看组件化架构实践
- 网易新闻构建优化:如何让你的构建速度“势如闪电”?
- …
四、高级kotlin强化实战
1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》
-
从一个膜拜大神的 Demo 开始
-
Kotlin 写 Gradle 脚本是一种什么体验?
-
Kotlin 编程的三重境界
-
Kotlin 高阶函数
-
Kotlin 泛型
-
Kotlin 扩展
-
Kotlin 委托
-
协程“不为人知”的调试技巧
-
图解协程:suspend
五、Android高级UI开源框架进阶解密
1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
六、NDK模块开发
1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习
七、Flutter技术进阶
1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)
…
八、微信小程序开发
1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……
全套视频资料:
一、面试合集
二、源码解析合集
三、开源框架合集
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓
以上是关于Framework底层服务,AMS|PMS|WMS原理分析的主要内容,如果未能解决你的问题,请参考以下文章
Android Framework——AMS、PMS的启动流程
android 11/12的 framework 框架systemserver源码中的AMS和WMS部分ProtoLog相关log的开放命令
android 11/12的 framework 框架systemserver源码中的AMS和WMS部分ProtoLog相关log的开放命令