主页

Android 系统架构 —— 资源的查找与打开

前言

在前面的学习中, 我们学习了资源管理器的初始化流程, 了解应用程序的资源是在什么地方管理的, 先回顾一下资源管理对象之间的依赖

资源管理整体依赖图

我们知道我们在开发过程中使用的资源主要有两种

  • 一种是通过文件相对路径访问的 asset 资源
  • 另一种是通过 ID 访问的 res 资源

它们访问的入口均为 Resources 对象, 也就是说最终会通过 AssetManager 获取真正的数据, 这篇文章就以获取 layout 的 XML 资源为例, 学习一下资源获取的流程

阅读更多

Android 系统架构 —— 资源管理的创建

前言

前面我们学习 App 资源的打包流程, 知晓了 resources.arsc 的结构组成, 我们在开发过程中想要访问资源需要通过如下的方式进行

Resources res = getContext().getResources();
res.getString(R.string.xxx);

我们在应用开发的过程中, 通常通过 Resources 对象来访问 app 的资源文件, 通过 aapt 编译的过程我们知道, R.string.xxx 是资源的 ID, 想通过 ID 获取到对应的资源, 只能够通过资源索引表 resources.arsc

我们在 Application 的 onCreate 中就可以通过 Resources 访问 app 的资源了, 因此本篇文章从 Application 的创建方法 makeApplication 为起点来探索一下资源管理类的创建流程

阅读更多

Android 系统架构 —— IMS 的事件分发

前言

上一篇文章中我们留下了很多疑问, 这篇文章我们就对此进行揭秘, 对 Android 窗体有所了解的开发者应该知晓, 当 ViewRootImpl 会通过 WindowManagerSession 向 WMS 发起请求创建一个窗体, 对应的实现如下

public class WindowManagerService extends IWindowManager.Stub {

    final WindowManagerPolicy mPolicy;// 在 WMS 的构造函数中赋值, 其实例为 PhoneWindowManager
    final WindowHashMap mWindowMap = new WindowHashMap();

    public int addWindow(Session session, IWindow client, int seq,
            LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
            DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
            
        .......
        synchronized(mWindowMap) {
            ......
            // 1. 创建一个窗体的描述
            final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], seq, attrs, viewVisibility, session.mUid,
                    session.mCanAddInternalSystemWindow);
            ......
            // 2. 给这个窗体描述打开一个输入通道, 用于接收屏幕的点击事件(事件分发)
            final boolean openInputChannels = (outInputChannel != null && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
            if  (openInputChannels) {
                win.openInputChannel(outInputChannel);
            }
            ......
            // 3. 将新创建添加的 WindowState 设置为 IMS 的焦点 Window, 即 native 层的 mFocusedWindowHandle
            if (win.canReceiveKeys()) {
                focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
                        false /*updateInputWindows*/);
                ......
            }
            .......
        }
        ......
        return res;
    }
}

上述代码即 WMS 添加一个 Window 的片段, 它主要做了如下几件事情

  • 创建窗体描述 WindowState
  • 打开窗体的输入通道 InputChannel
  • 更新 IMS 的焦点窗体
    • native 层的 mFocusedWindowHandle

IMS 能够将事件分发到窗体上 openInputChannel 输入通道的创建便是重中之重了, 这里我们主要对 openInputChannel 进行分析

阅读更多

Android 系统架构 —— IMS 的启动

前言

前面我们根据 SystemServer 的启动流程逐一分析了 AMS 和 PMS 的启动, 这里我们来看看 IMS 的启动流程

public final class SystemServer {
    
    private void startOtherServices() {
        ......
        InputManagerService inputManager = null;
        try {
            ......
            // 1. 创建 IMS
            inputManager = new InputManagerService(context);
            ......
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
            ......
            // 2. 启动 IMS
            inputManager.start();
        }
        ......        
    }
    
}

InputManagerService 的启动比 AMS 简单明了很多, 我们这里主要从这两个方面来分析 IMS 的启动

  • IMS 的创建
  • IMS 的启动

阅读更多

Android 系统架构 —— PKMS 之 应用的安装流程

前言

通过前面两篇文章的学习, 我们知晓了 PKMS 的启动过程

  • 解析备份文件
  • 扫描已安装的应用程序

不过 PKMS 除了负责管理已安装的应用程序之外, 还负责应用程序的安装操作, 我们 Android 端, 整个应用程序的安装主要有两种方式:

  • 通过 Session 发起(adb, 手动点击安装)
    • 提前将安装包拷贝到 “data/app/vmdl${sessionId}.tmp/” 目录下
    • 再通过 Session commit, 通知 PKMS 的 PKMS.installStage 进行安装
  • 通过系统的软件商店自动发起
    • 直接通过 PKMS 的 PKMS.installStage 进行安装

也就是说通过非系统软件商店的安装要多一步通过 Session 提前拷贝的过程, 这里我们为了更全面了解应用安装, 选择有 Session 通信的进行分析

阅读更多