Android广播事件流程与广播ANR原理深入刨析

目录
  • 序言
  • 一.基本流程和概念
  • 二.无序广播流程
    • 注册广播接收者流程
    • 广播通知流程
  • 三.有序广播流程
  • 四.广播ANR流程
  • 五.总结
  • 六.扩展问题

序言

本想写广播流程中ANR是如何触发的,但是如果想讲清楚ANR的流程,就不得不提整个广播事件的流程,所以就把两块内容合并在一起讲了。

本文会讲内容如下:

1.动态注册广播的整个分发流程,从广播发出,一直到广播注册者接收。

2.广播类型ANR的判断流程和原理。

PS:本文基于android13的源码进行讲解。

一.基本流程和概念

动态广播的流程其实是很简单的,整套流程都在java层执行,不涉及到native流程。

我们先来看一下最基本的流程图:

首先是广播注册者,向AMS注册广播接收器,AMS交给BroadcastQueue来处理。也就是说BroadcastQueue中装载所有的广播接收器。然后广播发出者向AMS发出广播,这时候AMS仍然会交给BroadcastQueue来处理,在其中找到符合条件的接受者,然后向接受者发出广播的通知。

然后我们再来了解一些最基本类的功能

ContextImp:Context的最终实现类,activity,application中的各种功能最终都是委托给其来处理的,广播功能自然也不例外。

ActivityManagerService:负责所有应用的Activity的流程,包括广播六层呢。至于为什么广播也由其来进行处理,而不是搞一个BroadcastManagerService,估计是觉得广播功能简单不需要单独设计Service吧。

BroadCastQueue:装载所有的动态广播接收器,静态广播也是由其来负责加载的,负责具体广播的分发工作。一种有三种类型,前台,后台,离线。

BroadcastReceiver:广播注册者

二.无序广播流程

首先我们了解下什么是无需广播和有序广播。简单来说,有序广播就是需要严格按照优先级,依次的执行接收动作,高优先级的广播接受者如果没有处理完,低优先级的广播接受者是无法收到广播的。无需广播就是没有顺序,各个广播接受者之间没有相互依赖关系。

无需广播,发送是sendBroadcast方法发送广播通知。

有序广播,需要使用sendOrderedBroadcast方法发送广播通知。

无序广播大体流程图如下:

注册广播接收者流程

1.APP侧,无论activity还是application,还是service,最终都是交给Context的实现类ContentImpl进行最终的处理的。所以注册广播的时候,最终调用的是ContentImpl的registerReceiver方法。

2.registerReceiver方法中通过binder,通知到AMS的registerReceiverWithFeature方法。

3.registerReceiverWithFeature方法中,首先做一些安全校验。

4.除了action类型,还会有scheme的类型,这里就不具体介绍了。

5.最终都会注册到IntentResolver类型对象mReceiverResolver上。

广播通知流程

1.仍然交由ContextImpl中的broadcastIntentWithFeature方法来处理。

2.broadcastIntentWithFeature通知到AMS的broadcastIntentLocked方法中。

3.首先从mReceiverResolver中查询,看是否存在接受者,如果存在,加入到registeredReceivers集合中。

registeredReceivers = mReceiverResolver.queryIntent(intent,
                        resolvedType, false /*defaultOnly*/, userId);

4.如果mReceiverResolver不为空,并且是无序广播,则根据intent找到所对应的BroadcastQueue(根据前台,后台,离线的类型)。

if (!ordered && NR > 0) {
            final BroadcastQueue queue = broadcastQueueForIntent(intent);
            BroadcastRecord r = new BroadcastRecord(queue, intent, ...);
            if (!replaced) {
                queue.enqueueParallelBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();
            }
            egisteredReceivers = null;
            NR = 0;
}

5.生成BroadcastRecord对象用来记录这次的action所对应的广播事件,然后加入到BroadcastQueue的mParallelBroadcasts集合中。然后通过scheduleBroadcastsLocked方法切换到主线程执行。这里要强调的是,无论是有序广播还是无序广播,都是通过这个方法来分发的。最终主线程会调用到processNextBroadcast方法。代码在上面5,6行。

6.processNextBroadcast方法中逻辑很多,我们这里先只讲无序广播的流程。上一步中,我们把BroadcastRecord加入到了mParallelBroadcasts中,所以这里发送广播的时候,直接遍历mParallelBroadcasts集合,然后通知接受者接收。具体的流程可以看流程图,这里就不细讲了。

具体代码如下:

while (mParallelBroadcasts.size() > 0) {
            r = mParallelBroadcasts.remove(0);
            r.dispatchTime = SystemClock.uptimeMillis();
            r.dispatchClockTime = System.currentTimeMillis();
            ...
            final int N = r.receivers.size();
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                deliverToRegisteredReceiverLocked(r,
                        (BroadcastFilter) target, false, i);//分发给接受者
            }
            addBroadcastToHistoryLocked(r);
        }

三.有序广播流程

有序广播流程和上面无序广播是类似的,最终请求AMS的方法其实也是broadcastIntentWithFeature方法,两者只是参数有区别而已。

我们仍然按照注册广播接受者和发送广播两个流程来讲,首先是注册广播。

注册广播接收者流程

注册的流程和无序广播是一样的。

广播通知流程

1.前面的流程和无序广播是一样的,唯一的区别是进入到AMS的broadcastIntentLocked方法后,执行逻略微有区别。有序广播,调用的是BroadcastQueue中的

enqueueOrderedBroadcastLocked方法,把BroadcastRecord对象最终注册到BroadcastDispatcher中的mOrderedBroadcasts集合中,然后在调用scheduleBroadcastsLocked方法切换到主线程,执行processNextBroadcastLocked的主流程。

下面介绍的都是processNextBroadcastLocked方法,也是广播事件分发的的核心流程代码:

2.processNextBroadcastLocked中,首先仍然去无序队列mParallelBroadcasts中查,这时候肯定是没有值的,所以跳过这个步骤。

3.然后通过mDispatcher.getNextBroadcastLocked(now);方法去BroadcastDispatcher中查找,方法实现如下,因为刚才应添加到了mOrderedBroadcasts集合中,所以这时候可以找到并返回BroadcastRecord对象。

4.BroadcastRecord.nextReceiver用来记录一系列有序广播执行到了第几个,0代表开始,如果为0,则记录一些必要信息。另外,会更新掉record的时间receiverTime,这一点很重要,下面ANR流程中会有涉及到。

代码如下:

int recIdx = r.nextReceiver++;
r.receiverTime = SystemClock.uptimeMillis();
        if (recIdx == 0) {
            r.dispatchTime = r.receiverTime;
            r.dispatchClockTime = System.currentTimeMillis();
            if (mLogLatencyMetrics) {
                FrameworkStatsLog.write(
                        FrameworkStatsLog.BROADCAST_DISPATCH_LATENCY_REPORTED,
                        r.dispatchClockTime - r.enqueueClockTime);
            }
            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
                    System.identityHashCode(r));
                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
                    System.identityHashCode(r));
            }
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
                    + mQueueName + "] " + r);
        }

5.发送一个延时广播,延时时间具体看是前台广播还是后台广播定义的。如果已经发送过并且未结束,则跳过。setBroadcastTimeoutLocked中的具体逻辑,第四章ANR流程中会讲到。

 if (! mPendingBroadcastTimeoutMessage) {
            long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
                    "Submitting BROADCAST_TIMEOUT_MSG ["
                    + mQueueName + "] for " + r + " at " + timeoutTime);
            setBroadcastTimeoutLocked(timeoutTime);
        }

6.如果接受者是BroadcastFilter类型,则把广播事件发送给接受者。

if (nextReceiver instanceof BroadcastFilter) {
    BroadcastFilter filter = (BroadcastFilter)nextReceiver;
    deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);

}

至此,processNextBroadcastLocked的方法暂时介绍完成,即然用暂时,那就说明后面还会涉及到。

7.接收者是LoadedApk中ReceiverDispatcher的内部类InnerReceiver,它是binder的服务端接收者,其performReceive方法收到通知后,会交给ReceiverDispatcher中的performReceive方法处理。

if (rd != null) {
   rd.performReceive(intent, resultCode, data, extras,
                            ordered, sticky, sendingUser);
}

所以,最终来处理广播信息的方法是ReceiverDispatcher中的performReceive方法。其中部分代码如下,getRunnable就是最终通知到我们注册的广播接受者的流程。如果getRunnable中的任务注册不成功的话,会直接发送信号通知回AMS。什么情况下会注册不成功呢?主线程Looper异常执行完并退出时就会发生。

 if (intent == null || !mActivityThread.post(args.getRunnable())) {
                if (mRegistered && ordered) {
                    IActivityManager mgr = ActivityManager.getService();
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing sync broadcast to " + mReceiver);
                    args.sendFinished(mgr);
                }
            }
        }

我们在来看一下getRunnable中返回的任务,我们仍然只贴核心代码:

                    if (receiver == null || intent == null || mForgotten) {
                        if (mRegistered && ordered) {
                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                    "Finishing null broadcast to " + mReceiver);
                            sendFinished(mgr);
                        }
                        return;
                    }
                   ...
                    try {
                       ...
                        receiver.onReceive(mContext, intent);
                    } catch (Exception e) {
                        ...
                    }
                    if (receiver.getPendingResult() != null) {
                        finish();
                    }

我们可以看到,先执行onReceive的回调,这里就会最终通知到我们的BroadcastReceiver中的onReceive方法。

然后我们在看一下finish方法:这个其实核心就是发送广播完成的信号给AMS:

public final void finish() {
            if (mType == TYPE_COMPONENT) {
                final IActivityManager mgr = ActivityManager.getService();
                if (QueuedWork.hasPendingWork()) {
                   ..
                    QueuedWork.queue(new Runnable() {
                        @Override public void run() {
                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                    "Finishing broadcast after work to component " + mToken);
                            sendFinished(mgr);
                        }
                    }, false);
                } else {
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing broadcast to component " + mToken);
                    sendFinished(mgr);
                }
            } else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
                if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                        "Finishing broadcast to " + mToken);
                final IActivityManager mgr = ActivityManager.getService();
                sendFinished(mgr);
            }
        }

最终,在BroadcastReceiver.PendingResult的sendFinished方法中,通过binder通知回AMS。

 am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
                                mAbortBroadcast, mFlags);

8.AMS的finishReceiver中,主要功能是先通过binder,找到所对应的BroadcastRecord,然后结束掉当前的这个事件流程,如果后面还有事件,则继续调用processNextBroadcastLocked方法,进行下一轮的广播事件分发。

r = queue.getMatchingOrderedReceiver(who);
if (r != null) {
     doNext = r.queue.finishReceiverLocked(r, resultCode,
                        resultData, resultExtras, resultAbort, true);
}
if (doNext) {
     r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
}

四.广播ANR流程

那么什么时候会导致广播ANR呢?这一套题,我估计能考倒90%的安卓开发者,单纯的无序广播,广播接受者中sleep几分钟,是不会产生广播类型ANR的,ANR只存在于有序广播并且广播接受者未及时响应。

其实了解完整个广播流程,我们ANR流程就好讲的多。我们只需关注整个流程中的几个点就好了。

触发广播监听者流程

1.首先第三章的第五小节中,我们讲到,通过setBroadcastTimeoutLocked方法设置一个延时的消息,消息的执行时间=当前时间+超时时间,此时伴随着广播通知到客户端的流程。

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

也就是说,一旦达到超时时间,那么就会发送BROADCAST_TIMEOUT_MSG类型的事件,就一定会执行broadcastTimeoutLocked方法。

2.broadcastTimeoutLocked方法中,会再一次进行判断,如果没有到执行时间,会重新触发一次setBroadcastTimeoutLocked的流程。

上面3.8中讲到,如果是有序广播,广播接收者收到消息后,会通过binder回调AMS通知事件处理完成,并重新进入processNextBroadcastLocked流程进行下一轮的分发,这时候,会更新掉上面用到的receiverTime时间。

3.processNextBroadcastLocked分发广播的时候,如果判断进入到了结束的环节,会主动取消注册BROADCAST_TIMEOUT_MSG类型的事件。

 if (r.receivers == null || r.nextReceiver >= numReceivers
                    || r.resultAbort || forceReceive) {
    ...
     cancelBroadcastTimeoutLocked();
}

一旦取消了超时类型消息的注册,自然也不会走到ANR逻辑。

这里有一点绕,所以我举个例子详细解释下,因为一开始我其实也被绕进去了。

假设我们的超时时间为10S,有序广播中有3个接收者,接收者1耗时5S,接收者2耗时6S,接收者3耗时4S,这时候,在接收者2处理中的时候,就会进入到broadcastTimeoutLocked的流程。但是此时,由于接收者1执行完其流程,所以更新了receiverTime时间,此时的超时时间变成5+10S,而当前为第10S,所以并不会超时。第14S的时候接收者3也完成流程,通知回AMS,取消了超时类型消息的注册,所以就不会再次走到broadcastTimeoutLocked的流程了。

所以,走到broadcastTimeoutLocked流程并不一定意味着就会发生ANR。我一开始就是被这个绕进去了。

五.总结

所以整个广播事件分发以及ANR触发流程,我们可以用下图来做一个总结:图片较大,建议另外开一个tab页查看:

六.扩展问题

1.有序和无序广播是怎么区分的?

答:sendOrderedBroadcast和sendBroadcast两个方法,其实最终broadcastIntentWithFeature方法中,就是一个参数不一样,倒数第三个boolean serialized。sendOrderedBroadcast为true,sendBroadcast为false。

2.发送一个广播,A进程中接收,广播接收者A中的onReceive方法中sleep100秒,是否一定会触发ANR?如果是或者不是?原因是什么?如果我们把广播改为有序广播呢?

答:

只有有序广播才会ANR,如果第一种情况如果是无序广播,自然不会ANR。

第二个答案是一般情况下是会的,因为广播接收者A中阻塞,导致AMS无法按时收到广播完成的信号,从而会引起ANR。除非进程A的主线程因为某种异常原因退出,不过这种情况下,onReceive方法自然也不会走到。

到此这篇关于Android广播事件流程与广播ANR原理深入刨析的文章就介绍到这了,更多相关Android广播事件流程内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android性能优化之捕获java crash示例解析

    目录 背景 java层crash由来 为什么java层异常会导致crash 捕获crash 总结 背景 crash一直是影响app稳定性的大头,同时在随着项目逐渐迭代,复杂性越来越提高的同时,由于主观或者客观的的原因,都会造成意想不到的crash出现.同样的,在android的历史化过程中,就算是android系统本身,在迭代中也会存在着隐含的crash.我们常说的crash包括java层(虚拟机层)crash与native层crash,本期我们着重讲一下java层的crash. java层cr

  • Android Crash与ANR详细介绍

    目录 Crash 空指针 角标越界 集合元素删除操作 异步操作后对界面元素的处理 Intent传递数据过大 在子线程中操作UI ANR Crash Crash是指程序闪退,导致APP不能正常使用.Crash产生的原因有很多,下面只是列举了一些常见原因. 空指针 空指针应该是项目中最容易产生crash的情况了,举个例子,我们获取某个对象的属性或方法时,这个对象为Null时,如何没有判空,则会出现空指针异常NullPointException,所以这就要求使用对象的时候进行非空判断,在这点,我觉得k

  • Android性能优化之ANR问题定位分析

    目录 前言 1 ANR原因总结 1.1 KeyDispatchTimeout 1.2 BroadCastTimeout 1.3 ServiceTimeout 1.4 ContentProviderTimeout 2 ANR问题解决 2.1 线下问题解决 2.2 线上问题解决 2.2.1 Bugly 2.2.2 FileObserver 2.2.3 WatchDog 前言 ANR(Application Not Response)应用程序未响应,当主线程被阻塞时,就会弹出如下弹窗 要么关闭当前ap

  • 解析Android ANR问题

    一.ANR介绍 ANR 由消息处理机制保证,Android 在系统层实现了一套精密的机制来发现 ANR,核心原理是消息调度和超时处理.ANR 机制主体实现在系统层,所有与 ANR 相关的消息,都会经过系统进程system_server调度,具体是ActivityManagerService服务,然后派发到应用进程完成对消息的实际处理,同时,系统进程设计了不同的超时限制来跟踪消息的处理. 一旦应用程序处理消息不当,超时限制就起作用了,它收集一些系统状态,譬如 CPU/IO 使用情况.进程函数调用栈

  • Android 应用Crash 后自动重启的方法小结

    前提 首先,我们肯定要在Application里面注册一个CrashHandler,监听应用crash public class TestApplication extends MultiDexApplication { private static TestApplication mInstance; @Override public void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler(ne

  • Android app会crash的原因及解决方法

    android main入口的commonInit()方法内处,有这么一句话, Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler)); 如果没有这句话,app就不会crash.不信,你往里面看, public KillApplicationHandler(LoggingHandler loggingHandler) { @Override public void uncaught

  • Android Java crash 处理流程详解

    目录 一.背景 二.App端Crash注册 2.1 commonInit() 2.2 KillApplicationHandler 类 2.2.1 ensureLogging() 2.2.2 ApplicationErrorReport 三.AMS端处理崩溃逻辑 3.1 AMS.handleApplicationCrash 3.1.1 AMS.handleApplicationCrashInner() 3.2 addErrorToDropBox() 3.3 AppErrors.crashAppl

  • 深入学习Android ANR 的原理分析及解决办法

    目录 一.ANR说明和原因 1.1 简介 1.2 原因 1.3 避免 二.ANR分析办法 2.1 ANR重现 2.2 ANR分析办法一:Log 2.3 ANR分析办法二:traces.txt 2.4 ANR分析办法三:Java线程调用分析 2.5 ANR分析办法四:DDMS分析ANR问题 三.造成ANR的原因及解决办法 四.ANR源码分析 4.1 Service造成的Service Timeout 4.2 BroadcastReceiver造成的BroadcastQueue Timeout 4.

  • 浅谈Android ANR的信息收集过程

    目录 一. ANR场景 二. appNotResponding处理流程 三. 总结 一. ANR场景 无论是四大组件或者进程等只要发生ANR,最终都会调用AMS.appNotResponding()方法,下面从这个方法说起. 以下场景都会触发调用AMS.appNotResponding方法: Service Timeout:比如前台服务在20s内未执行完成: BroadcastQueue Timeout:比如前台广播在10s内未执行完成 InputDispatching Timeout: 输入事

  • Android广播事件流程与广播ANR原理深入刨析

    目录 序言 一.基本流程和概念 二.无序广播流程 注册广播接收者流程 广播通知流程 三.有序广播流程 四.广播ANR流程 五.总结 六.扩展问题 序言 本想写广播流程中ANR是如何触发的,但是如果想讲清楚ANR的流程,就不得不提整个广播事件的流程,所以就把两块内容合并在一起讲了. 本文会讲内容如下: 1.动态注册广播的整个分发流程,从广播发出,一直到广播注册者接收. 2.广播类型ANR的判断流程和原理. PS:本文基于android13的源码进行讲解. 一.基本流程和概念 动态广播的流程其实是很

  • Spring数据库连接池实现原理深入刨析

    目录 Spring事务管理 环境搭建 标准配置 声明式事务 总结 SqlSessionFactory XML中构建SqlSessionFactory 获得SqlSession的实例 代码实现 作用域(Scope)和生命周期 SqlSessionFactoryBuilder(构造器) SqlSessionFactory(工厂) SqlSession(会话) Spring事务管理 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序

  • Android基于广播事件机制实现简单定时提醒功能代码

    本文实例讲述了Android基于广播事件机制实现简单定时提醒功能代码.分享给大家供大家参考,具体如下: 1.Android广播事件机制 Android的广播事件处理类似于普通的事件处理.不同之处在于,后者是靠点击按钮这样的组件行为来触发,而前者是通过构建Intent对象,使用sentBroadcast()方法来发起一个系统级别的事件广播来传递信息.广播事件的接收是通过定义一个继承Broadcast Receiver的类实现的,继承该类后覆盖其onReceive()方法,在该方法中响应事件.And

  • Android ANR原理分析

    目录 卡顿原理 卡顿监控 ANR原理 卡顿原理 主线程有耗时操作会导致卡顿,卡顿超过阀值,触发ANR. 应用进程启动时候,Zygote会反射调用ActivityThread的main方法,启动loop循环. ActivityThread(api29) public static void main(String[] args) { Looper.prepareMainLooper(); ... Looper.loop(); throw new RuntimeException("Main thr

  • Android基础知识之broadcast广播详解

    Android中的广播用的太多了,今天稍微总结一下. 按注册方式分为两种: 1.静态注册广播: 静态注册广播就是在androidManifest.xml文件中注册广播,假设我们要实现这样一个效果,在一个activity上点击按钮,发送一条广播,这条广播弹出一个toast,显示"静态"二字. 先看看广播接受者: public class MyBroadcast extends BroadcastReceiver { @Override public void onReceive(Cont

  • 关于Android触摸事件分发的原理详析

    目录 一:前言 二:说在前面的知识 三:整体流程 1:activity 2:window就是PhoneWindow 3:view group 4:view 四:一些关键点 五:从源码看触摸事件分发 总结 一:前言 最近在学Android的触摸事件分发,我觉得网上说的太杂太乱,而且有很多博客都有明显的错误.什么自顶向下分发,自下向顶分发,什么拦截又一直消费什么什么之类,非常难懂.为了自己将来回顾可以更好的理解这块知识,也为了后来之人可以更好的学习,我写下这篇博客. 二:说在前面的知识 点击,滑动,

  • Android AccessibilityService 事件分发原理分析总结

    目录 AccessibilityService 监听事件的调用逻辑 onAccessibilityEvent onIntercept AccessibilityService 事件的外部来源 AccessibilityServiceInfo AccessibilityManager AccessibilityManagerService AccessibilityServiceConnection 前言: 在了解了无障碍服务基础使用之后,我们来探究一下 AccessibilityService

  • Android中BroadcastReceiver(异步接收广播Intent)的使用

    Broadcast Receiver简介 Broadcast Receiver是Android的五大组件之一,使用频率也很高. 用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast().广播接收者(BroadcastReceiver)用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast().Context.sendOrderedBroadcast()或者Context.sendStickyBr

  • Android入门:广播发送者与广播接收者详细介绍

    一.广播发送者&广播接收者介绍 1.广播接收者 广播接收者简单地说就是接收广播意图的Java类,此Java类继承BroadcastReceiver类,重写: public void onReceive(Context context,Intent intent),其中intent可以获得传递的数据: 广播意图就是通过Context.sendBroadcast(Intent intent)或Context.sendOrderedBroadcast(Intent intent)发送的意图,通过这个语

  • Android编程输入事件流程详解

    本文实例讲述了Android编程输入事件流程.分享给大家供大家参考,具体如下: EventHub对输入设备进行了封装.输入设备驱动程序对用户空间应用程序提供一些设备文件,这些设备文件放在/dev/input里面. EventHub扫描/dev/input下所有设备文件,并打开它们. bool EventHub::openPlatformInput(void) { ... mFDCount = 1; mFDs = (pollfd *)calloc(1, sizeof(mFDs[0])); mDev

随机推荐