1. 用户接口registerReceiver

frameworks/base/core/java/android/content/ContextWrapper.java

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return mBase.registerReceiver(receiver, filter);
    }

frameworks/base/core/java/android/app/ContextImpl.java
    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiver(receiver, filter, null, null);
    }

@Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        return registerReceiverInternal(receiver, getUserId(),
                filter, broadcastPermission, scheduler, getOuterContext(), 0);
    }

@Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler, int flags) {
        return registerReceiverInternal(receiver, getUserId(),
                filter, broadcastPermission, scheduler, getOuterContext(), flags);
    }

class ContextImpl extends Context {
......
 
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
 
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, filter, broadcastPermission,
scheduler, getOuterContext());
}
 
private Intent registerReceiverInternal(BroadcastReceiver receiver,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context) {
IIntentReceiver rd = null;
if (receiver != null) {
// mPackageInfo是一个LoadedApk实例,它是用来负责处理广播的接收的
// context 是通过调用函数getOuterContext得到的
if (mPackageInfo != null && context != null) {
if (scheduler == null) {

// mMainThread.getHandler来获得一个Handler了,

//这个Hanlder是后面用来分发ActivityManagerService发送过的广播用的。

// 这里的成员变量mMainThread是一个ActivityThread实例
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
......
}
}
try {
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
return null;
}
}
 
......
 
}
// BroadcastReceiver
frameworks/base/core/java/android/content/BroadcastReceiver.java

// getHandler()
public final class ActivityThread {
......
final H mH = new H();
 
private final class H extends Handler {
......
 
public void handleMessage(Message msg) {
......
 
switch (msg.what) {
......
}
 
......
}
 
......
 
}
......
 
final Handler getHandler() {
return mH;
}
......
}

// 
frameworks/base/core/java/android/app/LoadedApk.java
    public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
            Context context, Handler handler,
            Instrumentation instrumentation, boolean registered) {

synchronized (mReceivers) {
            LoadedApk.ReceiverDispatcher rd = null;
            ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
            if (registered) {
// ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers = new ArrayMap<>();
        //由context获得ArrayMap<BroadcastReceiver, ReceiverDispatcher>>
//由BroadcastReceiver获得ReceiverDispatcher
                map = mReceivers.get(context);
                if (map != null) {
                    rd = map.get(r);
                }
            }
            if (rd == null) {
                rd = new ReceiverDispatcher(r, context, handler, instrumentation, registered);
                if (registered) {
                    if (map == null) {
                        map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                        mReceivers.put(context, map);
                    }
                    map.put(r, rd);
                }
            } else {
                rd.validate(context, handler);
            }
            rd.mForgotten = false;
   //获得后就会把它传给ActivityManagerService,以便接收广播
            return rd.getIIntentReceiver();
        }
    }

static final class ReceiverDispatcher {
//InnerReceiver实例,这是一个Binder对象,实现了IIntentReceiver接口,

//可以通过ReceiverDispatcher.getIIntentReceiver函数来获得,

//获得后就会把它传给ActivityManagerService,以便接收广播。

final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
......
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
......
}
......
}
 
......
 
final IIntentReceiver.Stub mIIntentReceiver;
final Handler mActivityThread;
......
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
......
 
mIIntentReceiver = new InnerReceiver(this, !registered);
mActivityThread = activityThread;

......
}
......
 
IIntentReceiver getIIntentReceiver() {
return mIIntentReceiver;
}
 
}
 
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
 
public Intent registerReceiver(IApplicationThread caller, IIntentReceiver receiver, IntentFilter filter, String permission) {
synchronized(this) {
// 函数首先是获得调用registerReceiver函数的应用程序进程记录块
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = getRecordForAppLocked(caller);
if (callerApp == null) {
......
}
}
 
List allSticky = null;
 
// Look for any matching sticky broadcasts...
Iterator actions = filter.actionsIterator();
if (actions != null) {
while (actions.hasNext()) {
String action = (String)actions.next();
allSticky = getStickiesLocked(action, filter, allSticky);
}
} else {
......
}

//广播接收器receiver保存一个ReceiverList列表中,这个列表的宿主进程是rl.app,这里就是MainActivity所在的进程了,
//在ActivityManagerService中,用一个进程记录块来表示这个应用程序进程,它里面有一个列表receivers,

//专门用来保存这个进程注册的广播接收器。接着,又把这个ReceiverList列表以receiver为Key值保存在

//ActivityManagerService的成员变量mRegisteredReceivers中,这些都是为了方便在收到广播时,快速找到对应的广播接收器的

ReceiverList rl
= (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp,
Binder.getCallingPid(),
Binder.getCallingUid(), receiver);
 
if (rl.app != null) {
rl.app.receivers.add(rl);
} else {
......
}
mRegisteredReceivers.put(receiver.asBinder(), rl);
}
  //创建一个BroadcastFilter来把广播接收器列表rl和filter关联起来,
//然后保存在ActivityManagerService中的成员变量mReceiverResolver中去
BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
rl.add(bf);
......
mReceiverResolver.addFilter(bf);
 
}
}
 
......
 
}

Android: registerReceiver代码实现相关推荐

  1. Android APP代码执行历史漏洞与攻击面分析

    文章目录 前言 错误的反射调用 漏洞根源分析 漏洞防御建议 反射调用思考 CVE-2020-8913 漏洞根源分析 动态加载Dex "寄生兽"漏洞 TikTok APP漏洞 代码执 ...

  2. android命令行工具 混淆,Android 混淆代码学习以及Android加密工具--APKProtect的使用ZZ...

    一:情景分析 有时候看到其他应用App的一些效果很炫,或者是功能实现很好就想着参考参考,于是乎,下载APK----反编译APK---查看源码....,但是悲剧来了....源码都是些a,b,c...等等 ...

  3. 黑客破译android开发代码真就那么容易?

    2019独角兽企业重金招聘Python工程师标准>>> 很多程序员辛辛苦苦开发出的android开发代码,很容易就被黑客翻译了. Google似乎也发现了这个问题,从SDK2.3开始 ...

  4. android 共享代码,Android团队成员间的代码共享!(Git+Github版)

    原创,转载请说明出处. 一. 这篇文章要解决什么问题,能学习到什么? 在android团队的开发中,少不了与队员之间的合作.为了避免我们傻瓜式地复制粘贴对方的负责的那部分功能代码,我们可以用svn或者 ...

  5. Android实用代码七段(五)

    1.展开.收起状态栏 public static final void collapseStatusBar(Context ctx) {         Object sbservice = ctx. ...

  6. Android实用代码(不定期更新)

    Android实用代码七段(一) 一抹火焰 整理(不定期更新) 前言 这里积累了一些不常见确又很实用的代码,每收集7条更新一次,希望能对大家有用. 声明: 欢迎转载,但请保留文章原始出处:)  博客园 ...

  7. Android Studio 代码自动提示无效

    Android Studio代码自动提示无效(not available in Power Save mode)的解决办法 问题描述: 今天用Android studio敲代码,突然间就没有代码提示了 ...

  8. 高通android开源代码下载

    高通android开源代码下载 开源网站https://www.codeaurora.org/projects/all-active-projects/android-msm,选择wiki,在Wiki ...

  9. 论初次修改 Android framework 代码

    点击打开链接 论初次修改 Android framework 代码 背景 公司产品需求,需要修改系统 framework 层的部分界面显示,包括声音调节.亮度调节.长按电源关机等. 准备 我并不是白手 ...

最新文章

  1. 百度搜索结果图文标识规则分析
  2. BZOJ 1132 [POI2008]Tro(极角排序)
  3. 【Java】使用Java调用Python的四种方法
  4. 82%开源软件兼容Windows
  5. kmap_atomic的细节以及改进
  6. Spring Boot ES 实战,直接拿来用!
  7. log4j.xml配置示例
  8. chrome浏览器历史版本
  9. 计算机基础cpu知识,CPU基础知识大全详解
  10. 多元统计分析朱建平pdf_应用多元统计分析课后答案朱建平版
  11. 微信朋友圈设计方案简述
  12. 用HTML创建幻灯片
  13. CTF-密码学-培根密码
  14. 超人工智能语音合成系统问世
  15. CSS3实现折角效果
  16. 数据挖掘—GEO,TCGA,Oncomine联合(三)GEO数据的下载和数据质量分析
  17. css换行文字隐藏,css 文本换行 文本溢出隐藏用省略号表示剩下内容
  18. 抢红包: 红包过期失效案例
  19. ps cs6 mac破解方法
  20. 飞飞cms添加广告html,飞飞影视cms-飞飞cms免费影视站程序

热门文章

  1. ABB机器人自制单轴偏移函数
  2. 基于MOS的防反接电路
  3. sts写java没有自动补齐,STS 创建 Maven 项目填坑
  4. SpringBoot合集笔记
  5. JDK之伪分享的情况下该使用填充还是@Contended
  6. 0x000000f怎么修复 win10_0xc000000f怎么修复,教你u盘重装win10系统出现0xc000000f的修复方法...
  7. layui radio 回显
  8. [android]不解锁刷机
  9. jquery - 定义二维数组
  10. 数据库可用于左右填充0的函数--->LPAD与RPAD