在Android系统开发过程中,经常碰到CPU占用率高、内存泄露、内存占用高等性能相关的问题,这时通常需要抓取系统的trace
日志,用以查看进程的CPU占用,内存分配等情况。怎么抓取系统trace, 这时一般需要用到系统性能相关的分析工具。这篇文章就以Android S
为例,说明Android开发中常用的一些性能优化工具的使用方法,主要包括如下几个工具:
DNS(Domain Name System)
即域名解析系统,是网络访问时用于将域名解析成对应IP地址的一种分布式网络服务。比如,要访问www.google.com
这个域名,Android
系统会首先发送一个UDP
请求到标准的53
端口系统的域名解析服务器,拿到对应的IP地址后才会与服务端建立连接。除了标准的DNS
服务外,目前还有HttpDNS
(DNS over Https, DoH
)以及基于TSL
的DNS
服务(DNS over TLS, DoT
)。
那么,Android
中DNS
解析的大致框架是怎么的?整个DNS
解析的流程又是怎么样的? 在看具体实现细节之前,我们不妨思考一下几个问题,想一想,如果我们自己从零开始为Android
设计一个DNS
系统,应该怎么做?
最近有同学在Android S(12)
上遇到了一个奇怪的网络问题,说自己的audio HAL
服务尝试通过以太网创建socket
与其他局域网的节点通讯时,总是提示Operation Not Permitted
。原先怀疑是Selinux
的问题,但是目前在开发版本中selinux
是完全关闭的;从问题发生的现象看,只有属于audioserver
这个UID
的进程才有问题,其他的如system/root
的进程则没有问题。
据此,我们可以推断,audioserver
这个UID
的进程没有相关权限,所以导致无法使用局域网的网络。记得在早前的Android
版本中,很多网络系统调用会通过netd
代理进行权限检查,比如socket/connect/bind
等系统调用都会先通过netdClient
这个库的接口进行权限检查,而后才真正进行系统调用。
最近开发投屏功能,需要对H.264
视频数据流进行解码,然后显示出来。Android原生的MediaCodec
虽然使用了硬件解码,但是延迟较大(超过300ms),无法满足要求。于是研究了下如何基于FFMPEG来做视频流的软解码。这里对整个过程做简要的总结,看下如何在Android Studio
中完成FFMPEG
的视频解码:
- 简单介绍下FFMPEG框架
- 如何利用交叉编译生成所需要的FFMPEG共享库, 以及如何进行
Android Studio
的配置 - FFMPEG解码H264的大致调用流程
之前帮着解决了项目中WIFI相关的问题, 一直想梳理下WIFI的框架, 方便后续代码阅读以及问题的解决. 恰好年初修改了车机上WIFI热点相关的一些代码, 重新看了下Android 10(Q)的逻辑, 于是想通过WIFI热点相关的功能作为切入点, 完整的梳理下Android WIFI的整体框架.
先不多说, 看下Android WIFI的大致框架:
这两天隔壁部门的同事反馈说新项目上, 车机(Android系统)上挂载的USB外设(一个可以上网的TBOX设备)无法通过ADB(Android Debug Bridge)进行连接. 心里有点纳闷, USB不都识别到了吗, 上次也把ADB相关的客户端都移植过去了, 为啥还会识别不到设备了? 只得从头开始理下ADB相关的代码与逻辑.先来看看ADB的基本原理.
ADB(全称Android Debug Bridge)是Android上用途十分广泛的调试工具, 可用于与开发设备进行连接;ADB命令既可以用来主机与设备之间传输文件, 也可以通过SHELL命令对设备进行操作. 如下所示, 是ADB的一个工作原理图:
最近新的项目又开始了, 开始还算顺利, 却不料碰到了一个奇怪的问题. 先来了解下问题的背景. 这个项目里, Android中有两个以太网网口, 一个用于内网通讯
开始我有点不相信竟然会有这样的问题, 但事实摆在面前, 我也不好抵赖, 于是自己找来一个板子, 看了下, 才逐渐找到答案. 问题的根源在于Android配置的策略路由fwmark
规则, 要解决问题, 只要我们将包含了
大致分如下几个部分来讲一讲这个问题:
- 介绍下什么是Policy Routing<策略路由>
- 分析具体的问题, 并给出方案
- 从源代码角度来分析下, 为何TCP无法建立, 但ping却可以
使用Android手机时, 我们不仅可以看到当前系统的流量使用情况, 还可以查看每个应用消耗了多少流量, 借此我们可以发现有那些流氓APP在偷偷在背后消耗流量.那么, Android是具体如何实现流量统计的? 又是如何对每个应用的流量使用进行监控? 这篇文章我们就来看看Android流量统计的具体实现原理.
大致说来, Android从如何几个方面进行流量统计:
- 统计每个网口当前发送/接收的流量数据
- 监控每个应用(对应唯一的UID)所消耗的流量
- 支持对总的流量配额进行限制, 如达到一定的流量阈值后, 会对网络进行限制
而具体到每个应用(比如system应用, UID=1000), Android还支持对应用内的每个socket进行标记(tag), 用于区分每个应用(UID)内部具体使用了那些流量.后面, 我们会讲到如何通过标签来区分UID内部的流量.
这两天顺着recovery模式下一个网络需求, 为了便于调试又在recovery下做了ADB功能. 在Android早期的如4.4版本, recovery模式下支持ADB配置起来比较简单(支持adb devices
/adb reboot
/adb pull/push
等常用指令), 但在Android 9.0下USB辅助设备一般都通过configfs
的方式来配置了, 因此相对来说要适配的东西就多一些, 如果额外要适配adb shell
命令, 则要修改adbd
的源代码了.这篇文章就来看看如何在Recovery模式下解决这几个问题.
在进入正题之前, 先了解下USB相关的基础知识.
USB全称是Universal Serial Bus
, 是一种广泛用于主机与外设之间的连接的串行总线.USB设备使用的是一种层级的结构, 最多可支持多达127个设备, 每个USB设备对应一个功能(function
), 比如USB打印机提供了打印服务; 存储设备则提供了存储数据的功能.
SELinux(Security Enhanced Linux)是Linux下的安全控制机制, 为进程访问系统资源提供了访问控制(access control)策略. 早期, Linux基于用户身份/用户组的DAC(Discretionary Access Control作为访问控制策略: 每个进程都有所属的UID, 每个文件都有所属的UID/GID以及文件模式(读写执行等), 一个进程是否可以访问某个文件就是基于UID/GID/文件模式来管理的.换句话说,只要某个资源序属于该用于或该用户组, 则该用户对该资源具有绝对控制权力, 这样一旦用户获得了root权限, 那么整个系统就成了肉鸡. 可见, DAC的安全控制策略比较粗放.
SELinux最初是由美国Utah大学与NSA(National Security Agency)的安全小组研究出来的安全框架FLASK演变而来, 后被合入到Linux 2.6版本.相较于DAC, SELinux采用的是更细粒度的MAC(Mandatory Access Control).对于DAC而言, 资源的权限是由每个用户自己控制的, 而MAC则将所有的权限收拢, 由一个统一的管理者(SELinux)统一来分配所有的资源权限, 如果访问者没有事先分配到某个资源的权限, 则不会允许访问.这样即使是root用户也要收到安全策略的约束. Android在4.3开始引入SELinux, 到了5.0版本之后, 则开始全面支持了.