Android Service、 BroadcastReceiver、ContentProvider ANR 原理详解

本文主要是介绍Android Service、 BroadcastReceiver、ContentProvider ANR 原理详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Service ANR:

启动Service 的时候,会调用到ActiveServices 类的 realStartServiceLocked方法。

    private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) throws RemoteException {//发送延迟消息bumpServiceExecutingLocked(r, execInFg, "create");}
    private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {boolean timeoutNeeded = true;long now = SystemClock.uptimeMillis();if (r.app != null) {r.app.executingServices.add(r);r.app.execServicesFg |= fg;if (timeoutNeeded && r.app.executingServices.size() == 1) {scheduleServiceTimeoutLocked(r.app);}}} else if (r.app != null && fg && !r.app.execServicesFg) {r.app.execServicesFg = true;if (timeoutNeeded) {scheduleServiceTimeoutLocked(r.app);}}r.executeFg |= fg;r.executeNesting++;r.executingStart = now;}

继续调用scheduleServiceTimeoutLocked

    void scheduleServiceTimeoutLocked(ProcessRecord proc) {if (proc.executingServices.size() == 0 || proc.thread == null) {return;}Message msg = mAm.mHandler.obtainMessage(ActivityManagerService.SERVICE_TIMEOUT_MSG);msg.obj = proc;mAm.mHandler.sendMessageDelayed(msg,proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);}

可以看到,里面拿到AtivityManagerService 的 Mainhandler 发送一个延期消息。

当Service 启动之后,就会移除掉消息。(ActiveServices)见下面:

private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,boolean finishing) {      if (r.executeNesting <= 0) {if (r.app != null) {     if (r.app.executingServices.size() == 0) {                  mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);

BroadcastReceiver ANR:

当处理广播的时候,会走到下面的processNextBroadcastLocked 方法:

    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {BroadcastRecord r;// First, deliver any non-serialized broadcasts right away.while (mParallelBroadcasts.size() > 0) {if (mService.mProcessesReady && r.dispatchTime > 0) {long now = SystemClock.uptimeMillis();if ((numReceivers > 0) &&(now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {broadcastTimeoutLocked(false); // forcibly finish this broadcastforceReceive = true;r.state = BroadcastRecord.IDLE;cancelBroadcastTimeoutLocked();}}

broadcastTimeoutLocked 里面会调用setBroadcastTimeoutLocked 方法,设置超时时间。

setBroadcastTimeoutLocked:

    final void setBroadcastTimeoutLocked(long timeoutTime) {if (! mPendingBroadcastTimeoutMessage) {Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);mHandler.sendMessageAtTime(msg, timeoutTime);mPendingBroadcastTimeoutMessage = true;}}

BroadcastHandler 是自己的Handler,但是Looper 是ActivityManagerService 的 MainHandler 的Looper.

private final class BroadcastHandler extends Handler {public BroadcastHandler(Looper looper) {super(looper, null, true);}@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case BROADCAST_INTENT_MSG: {if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");processNextBroadcast(true);} break;case BROADCAST_TIMEOUT_MSG: {synchronized (mService) {broadcastTimeoutLocked(true);}} break;}}}

处理ANR:

    final void broadcastTimeoutLocked(boolean fromMsg) {if (!debugging && anrMessage != null) {// Post the ANR to the handler since we do not want to process ANRs while// potentially holding our lock.mHandler.post(new AppNotResponding(app, anrMessage));}}

处理ANR:

    private final class AppNotResponding implements Runnable {private final ProcessRecord mApp;private final String mAnnotation;public AppNotResponding(ProcessRecord app, String annotation) {mApp = app;mAnnotation = annotation;}@Overridepublic void run() {mService.mAppErrors.appNotResponding(mApp, null, null, false, mAnnotation);}}

ContentProvider ANR:

ContentProvider Timeout是位于”ActivityManager”线程中的AMS.MainHandler收到CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息时触发。
ContentProvider 超时为CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10s. 这个跟前面的Service和BroadcastQueue完全不同, 由Provider进程启动过程相关.

ContentProvider 是在app 启动的时候,初始化的。初始话的时候,会发一条延迟消息,CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG

if (providers != null && checkAppInLaunchingProvidersLocked(app)) {Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);msg.obj = app;mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);}

当发布成功之后,就会移除掉这条消息。

    public final void publishContentProviders(IApplicationThread caller,List<ContentProviderHolder> providers) {if (wasInLaunchingProviders) {mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);}}}}

https://www.jianshu.com/p/1c827675f457

这篇关于Android Service、 BroadcastReceiver、ContentProvider ANR 原理详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131011

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu