安卓11动态分区(安卓动态分区解锁)

http://www.itjxue.com  2023-02-25 00:06  来源:未知  点击次数: 

Android - 文件系统与Android11 分区存储

Android文件系统分为 内部存储(internal storage) 和 外部存储(external storage)

1.1 用一个表格来直观对比一下两者:

1.2 应用的私有路径

应用在安装之后,系统会自动在内部存储和外部存储,分别建立应用的私有存储区域。

内部存储 : data/user/0/packageName

外部存储 : storage/emulated/0/android/data/packageName

当应用卸载或者清除数据后,该区域文件会被删除。

1.3 内外部存储图解

Android 10版本中,Google推出 分区存储 (scoped storage)的功能。

背景 :

分区存储功能是针对内置的外部存储来说的,很多应用喜欢在外部存储的根目录创建自己的文件夹,比如:storage/emulated/0/***

这样做的好处:1. 当不断向该目录存储时,应用自己的容量不会变化; 2. 当应用卸载时,该目录下文件不会被删除,可用于保存一些可持久性的文件。

但是也有坏处: 1. 对用户来说,会有很多垃圾文件存在于手机中;2. 只要获取到Read 和 Write权限,就可以随意访问外部存储的任何目录,信息安全存在隐患。

分区存储 :

除了应用的私有目录和公共目录,其他位置都称为 旧版存储位置 ,我们需要将旧版存储位置的数据迁移到能兼容分区存储的位置。

android存储分区和android11填坑

安卓设备的物理存储 分为两大块,内部存储和外部存储

存储分区,是android系统对APP访问外部存储 添加了限制;开启存储分区后 APP只能访问自己目录下的文件和公共文件,

需要特别指出的是android 10 虽支持存储分区 但可不开启,对于android11 来说,必须开启存储分区,android11必须使用存储分区,

即使设置 android:requestLegacyExternalStorage="true" 也无效

对原来的内部存储没有什么影响,但是对外部存储有影响;

外部 存储有两个区域 app私有区域和app共享区域;

例如:在android 10以下的手机设备上 调起相机拍照,使用 Uri.fromFile 的方式来创建照片文件是 没有问题的,但是 android11上,即使调起了相机拍照后 也无法成功保存照片

android 7 后支持 应用之间共享文件,这就是FileProvider的作用;

使用FileProvider 需要在清单文件中 声明,注意一下 android:authorities指定的属性值,尽可能的保证唯一性 一般以".fileProvider" 结尾

其中 file_paths文件在 Resource/xml 下,原来指定共享的 文件路径;

然后使用FileProvider API 来生成File的Uri路径;

这个"com.xx.fileprovider" 就是 授权认证的信息,如果填写的和清单文件中的不一致 会 导致文件读写时 错误;

android11哪个分区可以使用hideapi

新增分区。

Android11是分区存储的新式方法,来缓解储存方式,新增分区存储。可以共享多个区。

分区轻工业、重工业、住宅、办公楼及其他房屋在土地使用总平面布置图上的标志。

Android 11/R分区存储概念及权限特性的变更

在Android 10/Q之前应用开发者只要获取了WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE的权限后就能在sdcard/目录下肆无忌惮的创建文件和读取内容,而且这些被创建出来的文件不会随着应用卸载而删除,久而久之,用户手机的sdcard/目录下就会如杂草一般遍地开花,文件目录变得臃肿杂乱,而且应用之间创建的文件还会被彼此读取,就显得很不规范也不安全。

基于此,Google爸爸终于下定决心整治,于是推出了分区存储的概念,应用按照创建文件的类型(图片/音频/视频/文档)放到Google规划好的地方。

概念介绍就到这里,下篇研究一下分区存储的适配方案和文件操作MediaStore API。

Android Q动态分区super.img相关说明 解包super.img

Android 10上刷机使用了super.img,差分包多了dynamic_partitions_op_list,大致查询了下是新增了动态分区,从编译到生成差分包都做了一些修改,本次先整理大致分析,对这个更新点有初步的认识

一、编译方面

1.super.img的生成

通过编译的log可以看到,super.img的生成

make

build/make/core/Makefile

# If BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT is set, super.img is built from images in the

# $(PRODUCT_OUT) directory, and is built to $(PRODUCT_OUT)/super.img. Also, it will

# be built for non-dist builds. This is useful for devices that uses super.img directly, e.g.

# virtual devices.

ifeq (true,$(BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT))

$(INSTALLED_SUPERIMAGE_TARGET): $(INSTALLED_SUPERIMAGE_DEPENDENCIES)

$(call pretty,"Target super fs image for debug: $@")

$(call build-superimage-target,$(INSTALLED_SUPERIMAGE_TARGET),\

$(call intermediates-dir-for,PACKAGING,superimage_debug)/misc_info.txt)

编译log

[100% 1686/1686] Target super fs image for debug: out/target/product/k61v1_64_bsp/super.img

2020-01-06 16:14:22 - build_super_image.py - INFO ? ?: Building super image from info dict...

2020-01-06 16:14:22 - sparse_img.py - INFO ? ?: Total of 370303 4096-byte output blocks in 21 input chunks.

2020-01-06 16:14:22 - sparse_img.py - INFO ? ?: Total of 383438 4096-byte output blocks in 19 input chunks.

2020-01-06 16:14:22 - sparse_img.py - INFO ? ?: Total of 83534 4096-byte output blocks in 11 input chunks.

2020-01-06 16:14:22 - common.py - INFO ? ?: ? Running: "lpmake --metadata-size 65536 --super-name super --metadata-slots 2 --device super:4294967296 --group main:4292870144 --partition product:readonly:1516761088:main --image product=out/target/product/k61v1_64_bsp/product.img --partition system:readonly:1570562048:main --image system=out/target/product/k61v1_64_bsp/system.img --partition vendor:readonly:342155264:main --image vendor=out/target/product/k61v1_64_bsp/vendor.img --sparse --output out/target/product/k61v1_64_bsp/super.img"

2020-01-06 16:15:34 - common.py - INFO ? ?: lpmake I 01-06 16:14:22 ? 697 ? 697 builder.cpp:937] [liblp]Partition product will resize from 0 bytes to 1516761088 bytes

lpmake I 01-06 16:14:22 ? 697 ? 697 builder.cpp:937] [liblp]Partition system will resize from 0 bytes to 1570562048 bytes

lpmake I 01-06 16:14:22 ? 697 ? 697 builder.cpp:937] [liblp]Partition vendor will resize from 0 bytes to 342155264 bytes

2020-01-06 16:15:34 - build_super_image.py - INFO ? ?: Done writing image out/target/product/k61v1_64_bsp/super.img

make otapackage

build/make/core/Makefile

ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))

ifneq ($(BOARD_SUPER_PARTITION_SIZE),)

ifneq (true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS))

$(call build-superimage-target,$(INSTALLED_SUPERIMAGE_TARGET),\

$(call intermediates-dir-for,PACKAGING,superimage_debug)/misc_info.txt)

endif

endif

endif

build/make/core/Makefile

# Build super.img by using $(INSTALLED_*IMAGE_TARGET) to $(1)

# $(1): built image path

# $(2): misc_info.txt path; its contents should match expectation of build_super_image.py

define build-superimage-target

mkdir -p $(dir $(2))

rm -rf $(2)

$(call dump-super-image-info,$(2))

$(foreach p,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \

echo "$(p)_image=$(INSTALLED_$(call to-upper,$(p))IMAGE_TARGET)" $(2);)

mkdir -p $(dir $(1))

PATH=$(dir $(LPMAKE)):$$PATH \

$(BUILD_SUPER_IMAGE) -v $(2) $(1)

endef

编译log

2020-01-06 10:53:23 - build_super_image.py - INFO ? ?: Building super image from info dict...

2020-01-06 10:53:23 - sparse_img.py - INFO ? ?: Total of 370303 4096-byte output blocks in 21 input chunks.

2020-01-06 10:53:23 - sparse_img.py - INFO ? ?: Total of 385033 4096-byte output blocks in 19 input chunks.

2020-01-06 10:53:23 - sparse_img.py - INFO ? ?: Total of 83534 4096-byte output blocks in 11 input chunks.

2020-01-06 10:53:23 - common.py - INFO ? ?: ? Running: "lpmake --metadata-size 65536 --super-name super --metadata-slots 2 --device super:4294967296 --group main:4292870144 --partition product:readonly:1516761088:main --image product=out/target/product/k61v1_64_bsp/product.img --partition system:readonly:1577095168:main --image system=out/target/product/k61v1_64_bsp/system.img --partition vendor:readonly:342155264:main --image vendor=out/target/product/k61v1_64_bsp/vendor.img --sparse --output out/target/product/k61v1_64_bsp/super.img"

2020-01-06 10:54:27 - common.py - INFO ? ?: lpmake I 01-06 10:53:23 ?4178 ?4178 builder.cpp:937] [liblp]Partition product will resize from 0 bytes to 1516761088 bytes

lpmake I 01-06 10:53:23 ?4178 ?4178 builder.cpp:937] [liblp]Partition system will resize from 0 bytes to 1577095168 bytes

lpmake I 01-06 10:53:23 ?4178 ?4178 builder.cpp:937] [liblp]Partition vendor will resize from 0 bytes to 342155264 bytes

2020-01-06 10:54:27 - build_super_image.py - INFO ? ?: Done writing image out/target/product/k61v1_64_bsp/super.img

[100% 1019/1019] Package OTA: out/target/product/k61v1_64_bsp/full_k61v1_64_bsp-ota-mp1V6.zip

可以看出super.img的生成是使用build_super_image.py,传入了参数信息文件misc_info.txt

out/target/product/k61v1_64_bsp/obj/PACKAGING/superimage_debug_intermediates

use_dynamic_partitions=true

lpmake=lpmake

build_super_partition=true

super_metadata_device=super

super_block_devices=super

super_super_device_size=4294967296

dynamic_partition_list= product system vendor

super_partition_groups=main

super_main_group_size=4292870144

super_main_partition_list=product system vendor

super_image_in_update_package=true

product_image=out/target/product/k61v1_64_bsp/product.img

system_image=out/target/product/k61v1_64_bsp/system.img

vendor_image=out/target/product/k61v1_64_bsp/vendor.img

通过这里的参数可以了解到大概的信息

lpmake=lpmake

编译super.img可执行文件 目录host

dynamic_partition_list= product system vendor

super包含了product system vendor三个分区

那在super.img是怎么放的呢,解开看看就知道了

2.super.img的解包

super的解包需要工具lpunpack,但是默认没有编译,源码目录位于:system/extras/partition_tools/

直接 make lpunpack 之后会生成out/host/linux-86/lpunpack

首先我编译出super.img 首先确认是什么格式的 根据其他问题刷机的格式,我觉得这个是sparse格式

执行 file super.img 后还真是,所以。。。

第一步格式转换,转化为ext4

simg2img super.img super_ext4.img

第二步

创建目录super_ext4/ 存放解包后的文件

第三步

执行解包?out/host/linux-86/lpunpack???????super_ext4.img???super_ext4/

解包后在super_ext4/存放着是哪个完整的system.img vendor.img product.img 是ext4格式的,也可以通过mount挂载为文件目录

simg2imgsuper.img super_ext4.img

mkdir super_ext4

./lpunpack super_ext4.img super_ext4/

mkdir super_ext4/system/

./ext2rd super_ext4/system.img ./:super_ext4/system/

二、差分方面

1、整包

这里首先对于dynamic_partitions_op_list的生成进行确认

build/make/toos/releasetools/common.py

def _Compute(self):

self._op_list = list()

def append(line):

self._op_list.append(line)

def comment(line):

self._op_list.append("# %s" % line)

if self._remove_all_before_apply:

comment('Remove all existing dynamic partitions and groups before '

'applying full OTA')

append('remove_all_groups')

for p, u in self._partition_updates.items():

if u.src_group and not u.tgt_group:

append('remove %s' % p)

for p, u in self._partition_updates.items():

if u.src_group and u.tgt_group and u.src_group != u.tgt_group:

comment('Move partition %s from %s to default' % (p, u.src_group))

append('move %s default' % p)

for p, u in self._partition_updates.items():

if u.src_size and u.tgt_size and u.src_size u.tgt_size:

comment('Shrink partition %s from %d to %d' %

(p, u.src_size, u.tgt_size))

append('resize %s %s' % (p, u.tgt_size))

for g, u in self._group_updates.items():

if u.src_size is not None and u.tgt_size is None:

append('remove_group %s' % g)

if (u.src_size is not None and u.tgt_size is not None and

u.src_size u.tgt_size):

comment('Shrink group %s from %d to %d' % (g, u.src_size, u.tgt_size))

append('resize_group %s %d' % (g, u.tgt_size))

for g, u in self._group_updates.items():

if u.src_size is None and u.tgt_size is not None:

comment('Add group %s with maximum size %d' % (g, u.tgt_size))

append('add_group %s %d' % (g, u.tgt_size))

if (u.src_size is not None and u.tgt_size is not None and

u.src_size u.tgt_size):

comment('Grow group %s from %d to %d' % (g, u.src_size, u.tgt_size))

append('resize_group %s %d' % (g, u.tgt_size))

for p, u in self._partition_updates.items():

if u.tgt_group and not u.src_group:

comment('Add partition %s to group %s' % (p, u.tgt_group))

append('add %s %s' % (p, u.tgt_group))

for p, u in self._partition_updates.items():

if u.tgt_size and u.src_size u.tgt_size:

comment('Grow partition %s from %d to %d' % (p, u.src_size, u.tgt_size))

append('resize %s %d' % (p, u.tgt_size))

for p, u in self._partition_updates.items():

if u.src_group and u.tgt_group and u.src_group != u.tgt_group:

comment('Move partition %s from default to %s' %

(p, u.tgt_group))

append('move %s %s' % (p, u.tgt_group))

对比整包中的dynamic_partitions_op_list

# Update dynamic partition metadata

assert(update_dynamic_partitions(package_extract_file("dynamic_partitions_op_list")));

# Remove all existing dynamic partitions and groups before applying full OTA

remove_all_groups

# Add group main with maximum size 4292870144

add_group main 4292870144

# Add partition product to group main

add product main

# Add partition vendor to group main

add vendor main

# Add partition system to group main

add system main

# Grow partition product from 0 to 1516761088

resize product 1516761088

# Grow partition vendor from 0 to 342155264

resize vendor 342155264

# Grow partition system from 0 to 1158651904

resize system 1158651904

可以看出执行该文件在整包中的大致顺序:

1、移除所有的组,清空super

2、添加组

3、添加system product vendor组

4、添加分区并给到大小

那么通过整包中的语句,我们可以大致推出差分包执行流程,我做了几个包进行了验证

2、差分包

更新较少,只修改版本号

dynamic_partitions_op_list为空

新增大文件 对system分区重新划分大小

# Grow partition system from 1158651904 to 1577095168

resize system 1577095168

去除大文件 对system分区重新划分大小

# Shrink partition system from 1577095168 to 1158651904

resize system 1158651904

其实还有其他情况,既然整包可以删除添加组,那么差分包也可以进行这样的处理,不过目前对于我们常见的应该时这三种

大致相关就是这些,先对动态分区OTA有个了解,后面再进行详细整理

(责任编辑:IT教学网)

更多