close
当前位置: 物联网在线 > 技术文库 > android >

Android存储系统之架构篇

基于Android 6.0的源码,剖析存储架构的设计

一、概述

本文讲述Android存储系统的架构与设计,涉及到最为核心的便是MountService和Vold这两个模块以及之间的交互。上一篇文章 Android存储系统之源码篇 从源码角度介绍相关模块的创建与启动过程,那么本文主要从全局角度把握和剖析Android的存储系统。

MountService:Android Binder服务端,运行在system_server进程,用于跟Vold进行消息通信,比如 MountService 向 Vold 发送挂载SD卡的命令,或者接收到来自 Vold 的外设热插拔事件。MountService作为Binder服务端,那么相应的Binder客户端便是StorageManager,通过binder IPC与MountService交互。

Vold:全称为Volume Daemon,用于管理外部存储设备的Native daemon进程,这是一个非常重要的守护进程,主要由NetlinkManager,VolumeManager,CommandListener这3部分组成。

1.1 模块架构

从模块地角度划分Android整个存储架构:

Android存储系统之架构篇

图解:

Linux Kernel :通过 uevent 向Vold的NetlinkManager发送Uevent事件;

NetlinkManager :接收来自Kernel的 Uevent 事件,再转发给VolumeManager;

VolumeManager :接收来自NetlinkManager的事件,再转发给CommandListener进行处理;

CommandListener :接收来自VolumeManager的事件,通过 socket 通信方式发送给MountService;

MountService :接收来自CommandListener的事件。

1.2 进程架构

(1)先看看Java framework层的线程:

root@gityuan:/ # ps -t | grep 1212 system 1212 557 2334024 160340 SyS_epoll_ 7faedddbe4 S system_server system 2662 1212 2334024 160340 SyS_epoll_ 7faedddbe4 S MountService system 2663 1212 2334024 160340 unix_strea 7faedde73c S VoldConnector system 2664 1212 2334024 160340 unix_strea 7faedde73c S CryptdConnector ...

MountService运行在system_server进程,这里查询的便是system_server进程的所有子线程,system_server进程承载整个framework所有核心服务,子线程数有很多,这里只列举与MountService模块相关的子线程。

(2)再看看Native层的线程:

root@gityuan:/ # ps -t | grep " 387 " USER PID PPID VSIZE RSS WCHAN PC NAME root 387 1 13572 2912 hrtimer_na 7fa34755d4 S /system/bin/vold root 397 387 13572 2912 poll_sched 7fa3474d1c S vold root 399 387 13572 2912 poll_sched 7fa3474d1c S vold root 400 387 13572 2912 poll_sched 7fa3474d1c S vold media_rw 2702 387 7140 2036 inotify_re 7f84b1d6ac S /system/bin/sdcard

Vold作为native守护进程,进程名为”/system/bin/vold”,pid=387,通过 ps -t 可查询到该进程下所有的子进程/线程。

小技巧:有读者可能会好奇,为什么 /system/bin/sdcard 是子进程,而非子线程呢?要回答这个问题,有两个方法,其一就是直接看撸源码,会发现这是通过 fork 方式创建的,而其他子线程都是通过 pthread_create 方式创建的。当然其实还有个更快捷的小技巧,就是直接看上图中的第4列,这一列的含义是 VSIZE ,代表的是进程虚拟地址空间大小,是否共享地址空间,这是进程与线程最大的区别,再来看看/sdcard的VSIZE大小跟父进程不一样,基本可以确实/sdcard是子进程。

(3) 从进程/线程视角来看Android存储架构:

Android存储系统之架构篇

Java层:采用 1个主线程 (system_server) + 3个子线程 (VoldConnector, MountService, CryptdConnector);

Native层:采用 1个主线程 (/system/bin/vold) + 3个子线程 (vold) + 1子进程 (/system/bin/sdcard);

注:图中红色字代表的进程/线程名,vold进程通过pthread_create的方式创建的3个子线程名都为vold,图中只是为了便于区别才标注为vold1, vold2, vold3,其实名称都为vold。

Android还可划分为内核空间(Kernel Space)和用户空间(User space),从上图可看出,Android存储系统在User space总共采用9个进程/线程的架构模型。当然,除了这9个进/线程,另外还会在handler消息处理过程中使用到system_server的两个子线程: android.fg 和 android.io 。

Tips: 同一个模块可以运行在各个不同的进程/线程, 同一个进程可以运行不同模块的代码,所以从进程角度和模块角度划分看到的有所不同的.

1.3 类关系图

Android存储系统之架构篇

Android存储系统之架构篇

上图中4个蓝色块便是前面谈到的核心模块。

二、 通信架构
(责任编辑:ioter)

用户喜欢...

Android Weekly #276 安卓开发周刊 中文版

您是否了解过Android的Lifecycle-Aware库?(android.jlelse.eu) 我们如何了解Lifecycle-Aware库代码? Nishant Srivastava展示了可以跟踪活动或Lifecycle-Aware的Lifecycle Arch组件的片段,并相应地调整其行为。 为Mos...


Android Weekly #275 安卓开发周刊 中文版

MapMe — Android地图适配器 (medium.com) Josh Burton介绍MapMe,是一个用Kotlin编写的Android库,可以将适配器模式带到地图上。 赞助 CloudRail - 连接到API 10x更快 (cloudrail.com) 当我们用单一的界面连接到所...


使用Android Studio开发可独立运行(runnable)混淆过的Jar程序

之前开发Java程序一直都是使用Eclipse 开发Jar程序,现在开发基本上都已经弃用Eclipse了,但是有时偶尔开发个小的Jar程序,还要切换回去好麻烦,刚好前几天有人问几个相关的问题,就顺便整...


Android Weekly #274 安卓开发周刊 中文版

探索Android Oreo上的别后执行限制(medium.com) 在这篇文章中,Joe Birch解释了关于Android Oreo在后台运行服务的变化。 non-Time领主的time – 第5部分 (blog.stylingandroid.com) Mark Allison继续分析JSR 310 date和...


Android Weekly #273 安卓开发周刊 中文版

开源你的Android代码(android.jlelse.eu) 通过您的开源Android代码,您将(希望地)为Android社区提供有价值的代码,收到建设性的反馈,并与您最初建立的内容进行协作从而使您的代码变得更好。这...


Android Weekly #272 安卓开发周刊 中文版

Android Dev 101:每个初学者都应该知道的一些做法() 看一些初学者或媒介等级开发人员(不要错过任何人)应该知道的一些做法,以便更好地摆脱Android框架。 99.9% crash free sessions (medium.com) Chr...


Android Weekly #271 安卓开发周刊 中文版

依赖注入检查(medium.com) 在本文中,MihályNagy引入了依赖注入检查,一种开源注释处理器,可帮助您解决一些出现在所有JSR 330 DI库中常见的问题。 使用Android Studio插件提高效率 (blog.mindorks.com...


Android Weekly #270 安卓开发周刊 中文版

带有RxJava2的SOLID Android分析 (medium.com) 在这篇文章中,Aris Papadopoulos将解释如何正确创建一个分析系统,同时遵循SOLID原则,并使用RxJava2来解决问题。 (blog.stylingandroid.com) Java中的编程时间很难...


Android内存泄漏思考

Android内存泄漏是一个经常要遇到的问题,程序在内存泄漏的时候很容易导致OOM的发生。那么如何查找内存泄漏和避免内存泄漏就是需要知晓的一个问题,首先我们需要知道一些基础知识。...


Android Weekly #269 安卓开发周刊 中文版

在Google上快速提出操作 () Wolfram Rittmeyer分享了开始在Google上快速创建操作所需的所有信息(为了家庭与助理)。 RxJava中的错误处理(rongi.github.io) 一旦开始编写RxJava代码,你就会意识到有些事...