精华内容
下载资源
问答
  • sdcardfs 浅析

    2020-05-22 17:00:00
    sdcardfs是三星基于wrapfs框架开发的虚拟文件系统,并凭借其出色的IO性能,在Android O上替代FUSE(File system in Userspace),成功上位。不...

    sdcardfs是三星基于wrapfs框架开发的虚拟文件系统,并凭借其出色的IO性能,在Android O上替代FUSE(File system in Userspace),成功上位。不提FUSE单讲sdcardfs的文章算不上一次齐全的解析,所以本文在介绍sdcardfs的同时,也会对比sdcardfs和FUSE的框架与原理、分析为何FUSE被sdcardfs替代。希望通过对比解析清楚,那让我们一步步走进sdcardfs。

    sdcardfs的诞生

    sdcardfs是基于wrapfs开发的。wrapfs是什么、又是如何在FUSE,EXT的文件系统大家族中拥有一席之地呢?我们借助wrapfs的开发者Erez对文件系统的分类来分析一下:

    表1.文件系统的分类

    大多数文件系统可以归纳到表1总结的三类中。第一类是底层文件系统,内核空间的优势保障了这类文件系统的优越性能,但驾驭这类文件系统要求开发者对操作系统有深入理解,并不利于开发和调试。第二类用户层文件系统解决了这个痛点,用户层文件系统将晦涩难懂的底层文件系统藏在内核中,提供接口方便开发者调用开发新的文件系统。然而成也用户层,败也用户层,虽然比底层文件系统更容易开发与调试,但在用户态和内核态的来回切换导致性能大大降低。

    鱼与熊掌不可兼得的困境推动了第三种文件系统的诞生---可堆叠文件系统。它的性能表现接近底层文件系统,而开发成本接近用户层文件系统。wrapfs作为一种可堆叠文件系统的框架,为sdcardfs提供必需、或可选择的函数来帮助开发者开发。处于内核空间和用户空间的中间层的sdcardfs,并不真正地管理磁盘而是将操作命令和参数由上层传给底层。

    sdcardfs首先由三星开发,后由Google接手并应用于Android O,然而在AOSP官方承认sdcardfs之前,sdcardfs已经被众多手机厂商商用,比如华为也有自己开发的一套sdcardfs。

    为sdcardfs解除误会

    在梳理sdcardfs是如何运作之前,有几点常年围绕着sdcardfs的困惑点要先说明清楚。如果你也是第一次接触sdcardfs,一定会奇怪,sdcardfs是sd卡的文件系统吗?\sdcard分区又和他们是什么关系呢?

    我们先来说说sd卡和\sdcard分区,早期的安卓手机因为内部存储空间太小,所以会使用sd卡这种外部存储来增大可用空间。与此同时\sdcard分区也出现了,主要存储一些音乐电影等文件。然而这并不代表\sdcard分区就归sd卡所用。在某些同时拥有内部存储空间和sd卡的设备上,\sdcard实际代表内部存储空间,而\storage\sdcardfs1指外部存储。可以说sd卡的流行确实引出了\sdcard分区,但是这两者之间并没有一对一的所属关系。

    另外,sdcardfs文件系统也不是为了管理sd卡而开发的文件系统。而是为了解决其他两类文件系统的痛点而开发的。这就不得不先说说FUSE是怎么来的:当年的文件系统并没有权限管理的能力,当应用A和应用B同时将数据存在外部存储中,并且同时拥有外部存储的读写权限时,也意味着应用A、B有权限读到对方的数据。这是极其不安全的,尤其当应用的敏感信息也存储在外部存储的时候。所以FUSE的一大功能就是赋予权限管理的能力。然而FUSE受自身框架限制,不可避免地拥有IO latency,double caching等痛点得不到解决,以至于一度被sdcardfs所替代。

    sdcardfs也拥有case folding, 权限管理等其他功能。而本文作为入门级浅析,主要集中在sdcardfs的框架梳理和对比中,会更详细分析sdcardfs和FUSE框架有何不同,sdcardfs又是如何避免了FUSE的痛点。

    框架梳理-始于挂载

    和其他文件系统一样,使用sdcardfs也需要先挂载。在init_sdcardfs_fs()中首先为inode,dentry,packagelist申请slab缓存,然后调用resigter_filesystem注册文件系统。和init_sdcardfs_fs()对应自然会有exit_sdcardfs_fs()这个函数来注销sdcardfs,虽然并不常用。

    框架梳理-没有对比就没有伤害

    为了更好地理解sdcardfs何以替代FUSE,这里先梳理一下FUSE框架:

    图1.FUSE框架

    作为中间层的角色,FUSE拥有可加载的内核驱动模块(图中蓝色部分)以及提供API的用户空间的库(图中绿色部分)。其中内核驱动模块注册了/dev/fuse块设备来支持和用户态的通信,而用户空间的守护进程则时刻准备从/dev/fuse中读取并处理操作命令,然后将结果通过/dev/fuse返回给内核空间。用户空间提供的接口方便开发者忽略底层文件系统的存在,基于libfuse实现自定义的操作命令的处理方式。

    当操作挂载FUSE的路径时,用户的命令会随着图中的橘色剪头所示,经过如下一段旅程:1)当用户产生操作命令时,会通过glibc的系统调用将命令传递到内核层的VFS;2)VFS根据所在分区的文件系统将命令传递给对应文件系统的接口,这里挂载的文件系统当然是FUSE;3)FUSE内核模块收到命令后,会将命令分类放在某个队列中等待处理(包括pending,background,processing,interrupts,forgets五个队列,这里不展开讨论队列策略,感兴趣可参考文献1的3.1.1章节[1])/dev/fuse块设备会通过既定的通信协议将操作请求发送给上层FUSE守护进程来“处理”请求,而如何处理操作请求,取决于开发者在守护进程中的具体实现,这就是用户态文件系统开发者需要开发的部分。4)FUSE的守护进程将操作处理完后,将处理结果返回块设备/dev/fuse;5)FUSE内核模块将处理结果返回给VFS,VFS再将结果原路返回给上层。

    分析可发现整个流程中,发生了六次内核态与用户态的切换,这种高负担的操作解释了为何用户层文件系统的性能差。而FUSE确确实实减少了开发成本,如图所示,开发者并不需要了解底层文件系统如何工作,甚至不需要深入理解内核,根据libfuse提供的API接口可以快速开发出简单的定制化的文件系统。

    sdcardfs作为位于内核的中间层,和底层文件系统相比也减少了开发成本,并且处理操作命令的流程非常直观清晰,没有FUSE那么弯弯绕绕的流程:

    图2.带sdcardfs后的框架

    如图所示,sdcardfs仍然处于内核空间。它不同于FUSE,不是内核态和用户态的中间层,而是处于VFS与底层文件系统的中间。在没有sdcardfs的时候,虚拟文件系统层将操作命令直接向下传给指定的文件系统,比如EXT4或F2FS;加上sdcardfs之后,操作命令会经过VFS->sdcardfs->底层文件系统。流程简洁明了无需多言,问题的关键在于,sdcardfs如何将操作命令中的数据快速准确地转发给底层文件系统,并且不会因为sdcardfs自身的存在而影响原来的操作性能。

    在底层文件系统中,我们需要inode、dentry、file多个struct来定位某个文件或数据的所在位置。那么多了一层sdcardfs之后,如何保证IO性能呢?sdcardfs文件系统内也构建对应的inode、dentry、file结构体,并和底层文件系统的inode、dentry、file结构体链接起来,如图所示:

    图3.sdcardfs与底层文件系统的链接[3]

    通过图3的链接,如果知道sdcardfs的file结构体,可以找到底层文件系统的file结构体,继而定位其dentry和inode等信息。

    sdcardfs VS FUSE

    sdcardfs解决了FUSE的很多问题才成功上位的,比如上文提到的IO latency以及double caching。

    IO latency:依据第二节提到的FUSE的框架图,具体分析可得每一个读写命令都将经过六次的用户态和内核态的转换:1)用户空间的应用将系统调用传给FUSE内核驱动;2)FUSE内核驱动通知FUSE用户态守护程序有新的操作命令,用户态守护程序从dev/fuse读取命令;3)守护程序分析命令并下传给底层文件系统;4)底层文件系统执行操作,并将数据返回给FUSE守护程序;5)守护程序将结果通过dev/fuse传给FUSE内核驱动;6)FUSE内核驱动将结果返回给上层应用结束。而在sdcardfs的框架下,内核中仍然只是open, read, close三步操作。

    这种架构的劣势尤其体现在多个小文件的操作上。每一个小文件都将引起六次用户态和内核态的切换,这种框架下的用户态文件系统操作速度远远低于底层文件系统:在复制10000个50kb的小文件的实验中,FUSE比没有FUSE慢了40秒[2],如图4所示,在没有FUSE中间层的EXT4文件系统下,复制10000个50kb小文件需要17.27秒,而FUSE框架下需要1分03秒03毫秒。

    而sdcardfs从架构上避免了不用空间的频繁切换,将切换次数从6次减少到必需的2次切换,即操作命令下发和结果返回,使其性能接近底层文件系统。

    图4.复制大量小文件性能对比

    Double caching:在FUSE框架中的每一次读写调用,数据都会从内核内存复制到用户层缓存,原本的page cache因为FUSE的存在,又大了一倍。而sdcardfs只作为操作和参数的传递者而非处理者,所以从架构中避免了重复缓存的问题。

    总结

    本文基于与FUSE的对比,浅析了sdcardfs的框架和优势。正因为sdcardfs解决了FUSE IO操作延迟和重复缓存的主要痛点,使它在底层文件系统和用户层文件系统的夹缝中生存了下来。sdcardfs已不是当下流行的概念,然而sdcardfs还有很多可提升的空间。

    本文篇幅有限,还有很多内容没有覆盖到,比如sdcardfs的权限管理,case folding,storage tracking等功能的介绍。希望这篇会有后续,或者其他同学也针对sdcardfs的功能来篇分析。

    参考资料

    [1]用户空间文件系统FUSE:架构和实现细节

    [2]Diving into SDCardFS:How Google’s FUSE Replacement Will Reduce I\O Overhead

    [3]A Stackable File System Interface For Linux, Erez Zadok and Ion Badulescu

    扫码关注
    “内核工匠”微信公众号
    Linux 内核黑科技 | 技术文章 | 精选教程
    展开全文
  • [RK3288][Android6.0] Fuse将被SDCardFS替换

    千次阅读 2017-08-16 16:42:05
    很久以前,每台Android设备都使用外插microSD卡用于存储,这是因为内部的storage容量太小了。不过外部SD卡由于速度原因,所以用户体验不是太好。 早期的sd卡是被当做外部storage,这样就有两个目录/scdard和/sdcard...

    这里写图片描述


    External实际上是Internal

    很久以前,每台Android设备都使用外插microSD卡用于存储,这是因为内部的storage容量太小了。不过外部SD卡由于速度原因,所以用户体验不是太好。

    早期的sd卡是被当做外部storage,这样就有两个目录/scdard和/sdcard1,前者指内部storage,这部分其实就是内部sd或者emmc分出来的一个空间,后者指外部插入的卡。

    到后来随着内部存储容量的增大,Google开发了虚拟文件系统来存储application的data以及media文件,挂载点在/sdcard,实际上是在/data/media下,sdcard分区的存在是为了兼容。也就是说,对/sdcard的内容的增加会导致整个data分区空间的减少。

    我们现在所说的external storage是指实际的可插入和移除的microSD或者是内部的sd分区,即/sdcard或者/data/media,更多情况是指后者。


    Android虚拟文件系统:

    Android2.3之后,Google利用virtual filesystem把sdcard格式化为VFAT,VFAT利于外部设备访问设备,比如pc.但是这也带来了两个问题:
    1. 当PC连接Android设备时(作为usb mass storage时),sdcard分区需要先umount, 这时候设备端就无法访问sdcard分区了。
    不过此问题后来通过MTP的连接方式解决了,MTP的原理是PC请求文件列表,MTP从设备端返回PC所要的信息。PC发送删除请求时,MTP收到去删除对应的文件。
    2. 每个appliction可以访问sdcard分区下的所有目录以及文件,安全性得不到保证。


    Fuse:

    Fuse(filesystem in userspace)就是为了解决虚拟文件系统的问题而诞生。但是Fuse在使用过程中又出现了问题。

    • I/O Overhead

    正常的文件读写只要 open -> read/write -> close就可以,而且通过fuse的i/o操作却要多执行多个步骤(如下图),效率低。
    这里写图片描述
    以下是例子,明显fuse要慢很多。
    这里写图片描述

    • Double Caching

    用了Fuse之后,由于Linux有page cache机制,这样Fuse和EXT4 FS都会Cache相同的一份内容。


    SDCardFS:

    这种情况下,SDCardFS诞生,此机制基于WrapFS,由三星开发(已经用来一段时间),现在Google将它从Android 8.0开始引进。

    • SDCardFS的特征:

    这里写图片描述


    参考:

    Diving into SDCardFS: How Google’s FUSE Replacement Will Reduce I/O Overhead
    Why does FUSE on Android suck?
    Android O will be bringing the new SDCardFS to replace FUSE

    展开全文
  • android默认的方案,是基于用户空间文件系统,其最大的优点是移植性好。 分析android 默认fuse方案操作流程,如上图。可看出其最大缺点是: fuse文件系统和sdcard daemon 必须频繁的进行命令交互、数据交换, ...

    基于fuse的sdcard存储方案缺点

    • android默认的方案,是基于用户空间文件系统,其最大的优点是移植性好。

    在这里插入图片描述

    分析android 默认fuse方案操作流程,如上图。可看出其最大缺点是:

    • fuse文件系统和sdcard daemon 必须频繁的进行命令交互、数据交换,
    • 引入内核态和用户态切换系统开销。
    1. android用户数据空间data目录和用户sdcard目录,物理上在emmc中是同一个分区。
    2. 而文件系统也采用同一个文件系统ext4.如下图:

    在这里插入图片描述

    既然硬件上是emmc的同一个分区/软件上直接文件系统都是ext4 !那么问题来啦!

    我们是否有理由希望data目录和sdcard目录的存储性能接近呢?

    这个问题是值得期待的!

    但结果是我们期待的吗?请看测试结果:

    • data 目录基于ext4性能

    在这里插入图片描述

    sdcard 目录基于fuse+ext4性能

    在这里插入图片描述

    由以上测试数据,可以看出fuse性能表现令人失望!导致存储性能非常大的损耗!

    基于wrapfs的sdcard 存储方案优点

    既然前面说了fuse给存储系统带来了这么大损耗,那如何改进呢? 继续……

    基于wrapfs的android sdcard存储优化方案原理如下图:

    在这里插入图片描述


    由图上,可以看出,wrapfs将上层的请求直接传递给了底层ext4文件系统,看起来比fuse简单多了。
    那么同样的问题来啦!
    我们是否有理由希望data目录和sdcard目录的存储性能无限接近呢?

    请看测试结果:

    data目录基于ext4性能:
    在这里插入图片描述

    sdcard目录基于wrapfs + ext4性能
    在这里插入图片描述

    由以上测试数据,可以看出基于wrapfs sdcard存储性能已经无限接近ext4啦!

    总结:

    android基于fuse sdcard存储方案,移植性强,但性能差。特别是针对性能好的emmc,性能drop更明显。

    基于wrapfs sdcard存储方案,性能更强,越好的emmc,表现真好。但需要投入更多人力开发、维护。

    参考:https://www.2cto.com/kf/201412/363638.html

    展开全文
  • SDcardFS文件系统浅析(三) - SDcardfs挂载过程 源码kernel/fs/sdcardfs/main.c 挂载过程在init_sdcardfs_fs函数中,下面简要看下源码,分析下挂载过程 init_sdcardfs_fs函数分析 kernel/fs/sdcardfs/main.c ...

    SDcardFS文件系统浅析(三) - SDcardfs挂载过程

    源码kernel/fs/sdcardfs/main.c

    挂载过程在init_sdcardfs_fs函数中,下面简要看下源码,分析下挂载过程

    • init_sdcardfs_fs函数分析

      kernel/fs/sdcardfs/main.c
      static int __init init_sdcardfs_fs(void)
      {
      int err;
      
      pr_info("Registering sdcardfs " SDCARDFS_VERSION "\n");
      
      err = sdcardfs_init_inode_cache();//利用kmem_cache_create申请inode_info和inode_data 缓存
      if (err)
          goto out;
      err = sdcardfs_init_dentry_cache(); //利用kmem_cache_create申请dentry缓存
      if (err)
          goto out;
      err = packagelist_init(); //利用kmem_cache_create申请hashtab缓存
      if (err)
          goto out;
      err = register_filesystem(&sdcardfs_fs_type);
      out:
      if (err) {
          sdcardfs_destroy_inode_cache();
          sdcardfs_destroy_dentry_cache();
          packagelist_exit();
      }
      return err;
      }

      init_sdcardfs_fs函数相对比较简单主要是inode、dentry缓存和packagelist的初始化,初始化完成后注册SDcardfs文件系统

      1. 利用kmem_cache_create来申请inode和dentry缓存
      2. 利用kmem_cache_create来申请hashtable缓存
        • hashtable(散列表),其查找的效率很高,inode和dentry是内存中的数据,而数据的来源是硬盘,如果我们获得了inode和dentry数据,加到hashtable中,方便下一次的快速获取,而不是再次访问硬盘。
      3. 在inode、dentry、hashtable完成初始化后,调用register_filesystem,将sdcardfs_fs_type对象注册到内核。

      在将sdcardfs_fs_type注册到内核后,但还未完成mount过程,除了根文件系统系统是在内核引导阶段就被安装之外,其他文件或者由初始化脚本安装,或者由用户使用mount命令安装在已安装文件系统的某一个目录上。

    • 挂载过程

      在内核的启动过程中通过init_sdcardfs_fs将sdcardfs的sdcardfs_fs_type对象注册到内核中,之后在安卓的启动过程中将其挂载,其配置是否挂载sdcardfs取决于system.prop的一个系统属性

      persist.sys.sdcardfs=force_on //其会使系统在最终挂载data分区为sdcardfs
      注:在安卓8.0上,Google好像取消了该属性,因为8.0原生支持sdcardfs,没有该属性的配置的必要,但是在7.0的代码中看到它的身影

      通过配置该属性后,系统后再启动过程中判断该属性值来决定是否挂载data分区为sdcardfs,可以在sdcardfs_setup中看到其挂载过程,源码路径:

      安卓8.0 /system/core/sdcard/sdcard.cpp 需要翻墙

      /system/core/sdcard/sdcard.cpp
      static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path,
                               uid_t fsuid, gid_t fsgid, bool multi_user, userid_t userid, gid_t gid,
                               mode_t mask, bool derive_gid, bool default_normal) {
        // Try several attempts, each time with one less option, to gracefully
        // handle older kernels that aren't updated yet.
        for (int i = 0; i < 4; i++) {
            .............
            if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", //其通过该函数挂载sdcardfs
                      MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) {
                PLOG(WARNING) << "Failed to mount sdcardfs with options " << opts;
            } else {
                return true;
            }
        }
        return false;
      }
    • exit_sdcardfs_fs函数

      static void __exit exit_sdcardfs_fs(void)
      {
      sdcardfs_destroy_inode_cache();
      sdcardfs_destroy_dentry_cache();
      packagelist_exit(); //前三行利用kmem_cache_destroy来释放申请的inode、dentry、hashtable缓存
      unregister_filesystem(&sdcardfs_fs_type);
      pr_info("Completed sdcardfs module unload\n");
      }

      exit_sdcardfs_fs与init_sdcardfs_fs函数相反,比较简单,但一般不会用到

      1. 利用kmem_cache_destroy来释放申请的inode、dentry、hashtable缓存
      2. 在inode、dentry、hashtable释放后,调用unregister_filesystem,将sdcardfs_fs_type从内核中注销
    展开全文
  • Android关闭SdcardFS

    2019-08-26 15:36:37
    Author:Gary Date:2019-8-26 ... 由于项目先在Android6上进行实现的,现需要移植到Android8上。但是Android8上启用了SdcardFS,与原有设计中的Fuse不符,重新适配SdcardFS工作量比较大,找到如下方法可以关闭SdcardFS...
  • SDcardFS文件系统浅析(一) - sdcarfs历史 由于安卓O的已经官方支持...早期的android系统没有使用fuse文件系统后来android为了控制不同APP对文件访问的权限,使用了fuse文件系统。早期手机内置SD卡使用一个独立...
  • Android 9.0中sdcard 的权限和挂载问题

    千次阅读 2019-02-19 15:17:39
    版权声明:本文为博主原创文章,转载请...Android 从6.0 开始引入了Runtime permission,应用对于storage 进行读取、存储的时候,需要注册、申请对应的权限。Android 8.0中对于sdcard 读写只需要申请权限即可使用...
  • Android的世界中,应用程序可以使用的文件存储区域包括两个:内部存储空间、外部存储空间。这两个名称是在Android早期确定的,那时候大部分设备都提供内置的非易失性存储(内部存储空间)以及可移动的存储媒介,...
  • Android文件访问权限的管理机制以及SDCardFS 1. 原生Linux文件访问权限控制 原生的Linux操作系统是通过拥有者 ID(uid) 和群组 ID(gid)对文件的访问权限进行管理,如: user0@user0:testLinuxPermission$ ls -l 访问...
  • 早期的android系统没有使用fuse文件系统。后来android为了控制不同APP对文件访问的权限,使用了fuse文件系统。早期手机内置SD卡使用一个独立vfat文件系统格式的分区。使用fuse之后,将手机内置SD卡与 userdata分区...
  • sdcardfs之二权限控制

    千次阅读 2019-10-11 22:33:33
    sdcardfs如果没有独特的权限控制,只是转发用户态的参数和操作给底层文件系统就没有其存在的意义了。所以接下来关注sdcardfs是如何做到权限控制的。 1. linux的UGO文件权限生成 sdcardfs需要给vfs呈现linux标准的...
  • sdcardfs之一简介

    千次阅读 2019-10-11 22:17:53
    sdcardfs最初由三星开发,从Android8.0开始google开始接管sdcardfs用来替换原本的FUSE文件系统。(以下代码基于android 9.0的sdcardfs) 它跟sdcard(TF卡)没有关系,并不是一个磁盘文件系统。主要的功能是管理...
  • android.os.StatFs 一个模拟linux的df命令的一个类,获得SD卡和手机内存的使用情况 java.lang.Object android.os.StatFs 构造方法: StatFs (String path) 公用方法: 方法 : getAvai...
  • 一、重新挂载文件分区、 二、在 /system/lib/ 只读目录下创建文件、 三、修改 Android 系统文件的意义、
  • SDcardFS文件系统浅析(四)- cat 过程

    千次阅读 2018-05-24 22:01:48
    SDcardFS文件系统浅析(四)- cat 过程 我们暂时先跳过源码,通过在sdcardfs文件系统中cat一个文件的过程,来了解sdcardfs的调用过程,在对其调用流程有个清晰理解后再去看代码,会事半工倍。 通过ftrace设置graph...
  • Android Bootcamp 2017

    2017-02-09 16:18:01
    Day 3_ Graphics and Camera Android Bootcamp 2017 - Color Management Android Bootcamp 2017 — deqp Android Bootcamp 2017 — ...Android Bootcamp 2017—Sdcardfs Android Bootcamp 2017—Soong Build System
  • 一种动态实现挂载系统data分区的实现思路,即开机检测到ext4类的sd卡则挂载sdcard作为android系统的data分区,如果没有检测到sdcard就按照/etc/fstab存放的是系统中的文件系统信息挂载emmc作为系统的data分区,主要...
  • 本篇文章主要介绍了Android获取监听SD卡状态,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Android源码编译出来的镜像在运行的时候需要被加载, 在实际产品中, 这些镜像会通过特定的烧录方式烧录到emmc或者sd卡, 或者UFS闪存中,不过在emulator模拟中, 所有的镜像都会以文件形式挂载到系统中去. ...
  • frameworks\base\services\core\java\com\android\server\SystemServer.java frameworks\base\services\core\java\com\android\server\SystemServiceManager.java frameworks\base\services\core\java\...
  • Android 11 selinux 权限设置

    千次阅读 2021-09-12 15:43:18
    Android怎么写? 如何确认是SELinux 约束引起? 怎么抓取SELinux Log? 修改之后,怎么快速验证? 怎么从log中提取有效信息? 重点介绍 参考文档 架构 从上层到驱动层的调用流程,但是我们重点关注...
  • Android存储系统及存储的挂载 Android是基于Linux内核开发的,所以它的文件系统也是跟Linux文件系统类似。 首先我们来看Android存储的分类。 内部存储和外部存储、内置SD卡和外置SD卡 一般的Android手机都有2个存储...
  • 外置sd卡相关功能的时候遇到了在9.0上外置SD卡写入权限的问题,在 9.0 之前的平台,申请了 WRITE_MEDIA_STORAGE 的权限后,平台...android 9加入权限和动态申请都无法对外置SD卡创建文件夹 <uses-permission and..
  • Android P新特性

    千次阅读 2018-05-22 16:25:27
    转:http://gityuan.com/2018/04/08/android_p/引言2018年3月8日,谷歌发布了Android P的预览版,预计今年的Q3季度发布final release版本,有不少文章从开发者角度介绍了Android P的新特征,初步来看给感觉这次大...
  • PackageManagerService是Android系统核心服务之一,也是Android中最常用的服务之一。它主要负责的工作如下: 1. 解析AndroidManifest.xml文件,解析清单文件中的所有节点信息。 2. 扫描.apk文件,安装系统应用...
  • 使用Android模拟器调试linux内核

    千次阅读 2018-11-27 16:52:57
    使用Android模拟器调试linux内核为什么需要调试linux内核如何在Android上调试内核开发环境创建模拟器下载goldfish内核源码编译goldfish内核编译内核遇到的问题使用自己编译的...正好最近想研究Android上的sdcardfs源...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 206
精华内容 82
关键字:

androidsdcardfs