JasonWang's Blog

Android ANR处理流程

ANR即Application Not Responding, 应用无响应:当应用在某一个时间内无法及时响应用户请求时,系统会弹出一个对话框,告知用户应用无法响应。此时,用户可以选择关闭应用。对于Android应用来说,有一个UI线程(主线程)专门负责与用户交互,如果在此线程中进行耗时的操作,比如读取磁盘数据、从网络下载资源等IO操作,通常会导致UI线程阻塞,从而无法及时处理用户的输入请求,发生ANR。

Android是通过AMS跟WMS来监控应用响应状态的,一般有如下两种ANR情况:

  • 应用在给定时间内没有对用户输入(按键或者触屏操作)做出响应,通常是5s;
  • 广播接收者(BroadcastReceiver)没有在10s内处理完成;

对于输入无响应的情况,native监控到输入无响应时,则告知WMS,最后由WMS发送消息告诉AMS,某个应用发送了ANR,最后AMS会弹出Application Not Responding的对话框,请求用户关闭应用;对于广播无响应的情况是由AMS负责处理的,AMS对于每个发送出去给广播接收者的广播都有一个10s的定时,如果广播接收者在10s内尚未处理完,则视为无响应,因此也会弹出Application Not Responding

Zygote进程启动过程详解

与Java程序类似,Android应用程序框架层(Application Framework)以及APP运行在一个Dalvik Virtual Machine之上,那么,Android启动时框架层是如何初始化的,从何处初始化的?为此,Android在启动时会首先初始化一个专门的系统进程zygote来负责启动与初始化Java代码,比如系统服务进程system_server的启动,系统启动时各种Java服务的初始化,APP资源文件的加载,APP进程的创建与启动。这篇文章,主要讲zygote进程的两个问题:

  • zygote进程如何初始化的;
  • APP进程是如何通过zygote创建的?
Android Phone进程启动过程分析

之前解决一个开机搜网慢的问题时,发现由于Phone进程起来以后才会主动连接RILD,因而在一定程度上Phone进程启动的时间会影响网络状态注册的快慢。适当的将Phone进程提前,可以将网络注册时间提前一点,让状态栏中信号显示的时间提前。那么,Android中作为系统的核心进程之一,Phone进程是如何启动的了?

本文参考代码为Android NN7.0, RIL运行机制请参考: Android RIL概述

Android Launcher工作原理

Android系统启动完成后,第一个启动的Activity就是主界面应用程序Launcher,相当于电脑的桌面。Launcher界面可以看到系统中安装的所有APP,点击APP即可启动该APP应用了。那么,Launcher到底是如何启动的以及如何自定义自己的Launcher了?这篇文章我们就来讲讲这两个问题。

Android RILD详解

前言

在上一篇文章里(http://sniffer.site/2016/11/29/Android-RILD%E8%AF%A6%E8%A7%A3/),简要介绍了Android RIL的架构。这一篇文章,就来看一看RILD(RIL Daemon)相关的内容。Android RIL在HAL(Hardware Abstract Layer)层(C++层)由三个部分组成:

  • RILD是系统的守护进程,主要用于初始化LIBRIL以及启动厂商自定义的Vendor RIL;
  • LIBRIL库被RILD初始化完成后,用于与Vendor RIL之间进行交互,负责接收、发送指令;
  • Vendor RIL库是第三方厂商自定义的一个库,用于向Modem发送指令或者接收来自LIBRIL或者Modem的指令, Android有一个基于AT指令的默认参考实现(reference-ril)
Android RIL概述

前言

Android作为一个通用的移动平台,其首要的功能就是通话、短信以及上网等通信功能。那么,从系统的角度来看,Android究竟是怎么实现与网络的交互的了? 这篇文章里,就来看一看Android中负责通信功能的Telephony中间层,通常也被称之为RIL(Radio Interface Layer)的具体实现原理与架构。

Android手机要实现与网络端的通信,需要跨越两个层:

  • RIL Java(RILJ):负责将上层APP的通信请求发送给HAL层;
  • RIL C++(RILD): 系统守护进程,负责将RILJ的请求命令发送给CP(Communication Processor)
Android系统时间自动更新机制

Android系统是如何更新时间的了?Android提供了两种时间更新方式,NITZ和NTP,其中NITZ是基于移动基站通信更新的,与语音通话时相同的一个通道,而NTP则是通过数据通道(此时手机必须能上网)来更新的。这里,就来了解下这两种时间更新方式具体是如何工作的吧?

Android Binder入门

背景

如今的操作系统都支持多进程并发执行, 系统一般都存在多种不同的服务运行在多个进程当中。那么,进程与进程之间如何通信,即跨进程通信(IPC, Inter-Process Communication)是如何进行的呢? Linux已有好几种IPC机制:

  • Signals: 最早的IPC方式,一个进程通过发送信号给另一个有相同UID/GID的进程或者在同一进程组的进程
  • Pipes(包括 named pipes): Pipes是一个单向的用于连接一个进程的标准输出与另一个进程的标准输入的字节流通道
  • Sockets: 双向的通道,两个进程通过打开同一个socket进行通信
  • Message queues: 一个进程将消息写入消息队列,另一个进程从改队列中读取消息
  • Semaphores: 信号量是一个可以被多个进程读写的共有变量
  • Shared Memeory: 一个系统的内存区域,通过将其映射到两个不同进程的虚拟地址空间,因此每个进程都可以访问该地址空间
  • D-Bus(Desktop Bus): 用于桌面组件与服务通讯的协议
Android Fota升级

Android设备的系统升级有两种方式:(1)下载更新包到手机后,手动安装,即所谓“卡刷包”的形式更新;(2) 通过 Over-the-air(OTA)的方式更新系统,简称为FOTA(Firmware Over The Air),FOTA升级有两种方式,一种是Full update,即将整个IMG置于升级包中,然后将升级包直接拷贝到系统;一种是Increamental update,即通过增量式的差分包,只是将系统更新的部分打包,然后以打补丁的形式应用到系统。

在介绍FOTA升级流程之前,先来看看Android系统的分区。一般,Android系统有如下几个分区(不同厂商、设备可能有差异):

  • /boot: 用于系统启动的分区,主要包括Kernel和ramdisk。主要用于挂载system和其他分区,并加载system分区的代码。没有该分区,手机是无法正常启动的;

ramdisk.img is a small partition image that is mounted read-only by the kernel at boot time. It only contains /init and a few config files. It is used to start init which will mount the rest of the system images properly and run the init procedure. A Ramdisk is a standard Linux feature.

  • /system:该分区包含了出了 kernel/ramdisk之外的系统应用程序和库文件;正常操作情况下,该分区是只读状态;
  • /recovery:用于系统升级打补丁,包含了一个完整的Linux操作系统和一个特殊的recovery包。FOTA升级时,下载完更新包后,进入recovery模式,recovery程序会读更新包,然后将各个patch应用到各个分区;
  • /misc:升级时,recovery用于存储相关信息的小分区
  • /data:主要包含了用户的数据,如联系人、短信、设置以及安装的应用。清除该分区等同于将手机重置,OTA不会影响该分区;
  • /cache:用于存放需要经常访问使用的数据和应用组件,访问该分区需要特殊的应用程序权限;OTA升级时下载的升级包就位于该分区;