Android广播的两种类型:

1.静态广播

2.动态广播

静态注册广播:

Manifeast中的代码块:

<receiver
android:name=".broadcast.MyStaticReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="husanity"/>
</intent-filter>
</receiver>
MyStaticReceiver这个类里面很简单,只做了打印收到的信息:
package com.hxc.supreme.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast; import com.hxc.supreme.utils.ToastUtil; public class MyStaticReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
Log.i("MyStaticReceiver", "onReceive: "+intent.getStringExtra("info"));
}
}

然后就是主界面一个点击按钮,布局文件很简单:

package com.hxc.supreme.activity;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; import com.hxc.supreme.R; /**
* created by huxc on 2017/9/28.
* func:Android广播详解
* email: hxc242313@qq.com
*/ public class BroadcastActivity extends AppCompatActivity implements View.OnClickListener { private TextView tvStaticBroadcast;
private TextView tvDynamicBroadcast; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast);
tvStaticBroadcast = findViewById(R.id.tv_static_broadcast);
tvDynamicBroadcast = findViewById(R.id.tv_dynamic_broadcast);
tvStaticBroadcast.setOnClickListener(this);
tvDynamicBroadcast.setOnClickListener(this);
} @Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_static_broadcast:
sendBroadcast();
break;
case R.id.tv_dynamic_broadcast:
break;
}
} private void sendBroadcast() {
Intent intent = new Intent();
intent.setAction("husanity");
intent.putExtra("info", "这是一条静态广播");
sendBroadcast(intent);
} }

然后看一下logcat中的日志输出:

02-15 15:33:14.300 15384-15384/com.hxc.supreme I/MyStaticReceiver: onReceive: 这是一条静态广播

然而,在Android8.0及以上的系统中,收不到静态广播!Google了一下发现,谷歌在8.0后为了提高效率,删除了静态注册,防止关闭App后广播还在, 造成内存泄漏, 现在静态注册的广播需要指定包名!!!

意思就是在8.0以后Google官方推荐用动态注册替换静态注册,那我们就指定一下包名看看是否管用:

代码只改动了发送广播的方法:

 private void sendBroadcast() {
Intent intent = new Intent();
intent.setPackage(getPackageName());//Android8.0以上需指定包名
intent.setAction("husanity");
intent.putExtra("info", "这是一条静态广播");
sendBroadcast(intent);
}

看下logcat的输出日志:

02-15 15:46:21.891 11181-11181/com.hxc.supreme I/MyStaticReceiver: onReceive: 这是一条静态广播

事实是证明可以的,但是Google推荐使用动态注册,那我么接下来就看一下动态注册的使用方式。

动态注册广播:

直接上代码:

package com.hxc.supreme.activity;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; import com.hxc.supreme.R; /**
* created by huxc on 2017/9/28.
* func:Android广播详解
* email: hxc242313@qq.com
*/ public class BroadcastActivity extends AppCompatActivity implements View.OnClickListener { private TextView tvStaticBroadcast;
private TextView tvDynamicBroadcast;
private DynamicReceiver dynamicReceiver; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast);
tvStaticBroadcast = findViewById(R.id.tv_static_broadcast);
tvDynamicBroadcast = findViewById(R.id.tv_dynamic_broadcast);
tvStaticBroadcast.setOnClickListener(this);
tvDynamicBroadcast.setOnClickListener(this);
dynamicReceiver = new DynamicReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("husanity");
registerReceiver(dynamicReceiver, intentFilter);
} @Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_static_broadcast:
sendBroadcast();
break;
case R.id.tv_dynamic_broadcast:
sendDynamicBroadcast();
break;
}
} private void sendBroadcast() {
Intent intent = new Intent();
intent.setPackage(getPackageName());//Android8.0以上需指定包名
intent.setAction("husanity");
intent.putExtra("info", "这是一条静态广播");
sendBroadcast(intent);
} private void sendDynamicBroadcast() {
Intent intent = new Intent();
intent.setAction("husanity");
intent.putExtra("extra", "这是一条动态广播");
sendBroadcast(intent); } class DynamicReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
Log.i("BroadcastActivity", "onReceive: " + intent.getStringExtra("extra")); }
} @Override
protected void onDestroy() {
super.onDestroy();
//onDestroy中需要反注册,用来优化内存空间避免内存泄漏
unregisterReceiver(dynamicReceiver);
}
}

看下log cat打印日志:

02-15 16:08:25.559 11597-11597/com.hxc.supreme I/BroadcastActivity: onReceive: 这是一条动态广播

可以看到结果也是能够收到广播的,那么既然两种都可以,那静态注册和动态注册到底有什么区别呢?

静态注册和动态注册的区别:

通过一个拨打电话然后监听收到的打电话的广播来看看两者的区别:

manifest修改:

<receiver
android:name=".broadcast.MyStaticReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<!--<action android:name="husanity"/>-->
<!--设置打电话对应的action-->
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>

Java代码中动态广播修改:(Android6.0之后的获取通讯录权限需要动态获取)

<receiver
android:name=".broadcast.MyStaticReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<!--<action android:name="husanity"/>-->
<!--设置打电话对应的action-->
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter> </receiver>

静态广播修改:

package com.hxc.supreme.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast; import com.hxc.supreme.utils.ToastUtil; public class MyStaticReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
Log.i("MyStaticReceiver", "静态广播接收到您正在拨打电话 " + getResultData());
}
}

当我们直接从BroadcastActivity这个界面回到手机界面打电话时,看一下logcat的输出:

02-15 16:30:46.162 4744-4744/com.hxc.supreme I/BroadcastActivity: 动态广播接收到您正在拨打电话 10001
02-15 16:30:46.200 4744-4744/com.hxc.supreme I/MyStaticReceiver: 静态广播接收到您正在拨打电话 10001

然后从BroadcastActivity界面先返回上级界面然后再回到手机界面拨打电话,此时的logcat输出:

02-15 16:40:04.007 4744-4744/com.hxc.supreme I/com.hxc.supreme.activity.BroadcastActivity: onDestroy:
02-15 16:40:27.189 4744-4744/com.hxc.supreme I/MyStaticReceiver: 静态广播接收到您正在拨打电话 10001

这是只能收到静态注册的广播,无法收到动态注册的广播了。

所以,静态广播是常驻型广播,不随界面的销毁而销毁,只要程序没被杀死,收到了对应的广播通知时就会调用程序;

而动态注册广播跟随界面的生命周期,不要忘了在页面销毁之前释放广播。

有序广播和普通广播:

普通广播:

通过Context.sendBroadcast()方法来发送,它是完全异步的。所有的receivers(接收器)的执行顺序不确定,因此所有的receivers(接收器)接收broadcast的顺序不确定。
 
有序广播:
通过Context.sendOrderedBroadcast来发送,所有的receiver依次执行。BroadcastReceiver可以使用setResult系列函数来结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播,使用该广播不再传送到别的BroadcastReceiver。可以通过在intent-filter中设置android:priority属性来设置receiver的优先级,优先级相同的receiver其执行顺序不确定。
 
举例:
短信拦截:你可以设置自己的app的广播接收器的级别高于系统原来的级别,并且收到后中断往下传播,这样的话收件箱里面就不会收到短信了。

Android 四大组件之broadcast的理解的更多相关文章

  1. android四大组件之Broadcast

    广播的概念 现实中:我们常常使用电台通过发送广播发布消息,买个收音机,就能收听 Android:系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件.Androi ...

  2. [Android基础]Android四大组件之BroadCast

    BroadCast的定义: 广播是一种订阅--通知 事件,广播接收者向Android系统 register (订阅广播),广播发送者向Adnroid系统 sendBroadCast(发送广播),然后A ...

  3. 【Android开发日记】之入门篇(六)——Android四大组件之Broadcast Receiver

    广播接受者是作为系统的监听者存在着的,它可以监听系统或系统中其他应用发生的事件来做出响应.如设备开机时,应用要检查数据的变化状况,此时就可以通过广播来把消息通知给用户.又如网络状态改变时,电量变化时都 ...

  4. Android四大组件之BroadCast(续)

    1.哪一个方法可以发送广播? activity.sendbroadcast or context.sentbroadcast or service.sendbroadcast 2.创建广播接受程序必须 ...

  5. Android 四大组件之service与Broadcast

    Android 四大组件之一:service: Service有五个生命周期:onCreat,onStartCommand, onBind,onUnbind, onDestroy 主要有绑定和非绑定两 ...

  6. Android四大组件之一“广播”

    前言 Android四大组件重要性已经不言而喻了,今天谈谈的是Android中的广播机制.在我们上学的时候,每个班级的教室里都会装有一个喇叭,这些喇叭都是接入到学校的广播室的,一旦有什么重要的通知,就 ...

  7. 第九章:四大组件之Broadcast Receiver

    第九章:四大组件之Broadcast Receiver   一.广播的功能和特征 广播的生命周期很短,经过调用对象-->实现onReceive-->结束,整个过程就结束了.从实现的复杂度和 ...

  8. Android 四大组件之“ BroadcastReceiver ”

    前言 Android四大组件重要性已经不言而喻了,今天谈谈的是Android中的广播机制.在我们上学的时候,每个班级的教室里都会装有一个喇叭,这些喇叭都是接入到学校的广播室的,一旦有什么重要的通知,就 ...

  9. Android四大组件与进程启动的关系(转)

    一. 概述 Android系统将进程做得很友好的封装,对于上层app开发者来说进程几乎是透明的. 了解Android的朋友,一定知道Android四大组件,但对于进程可能会相对较陌生. 一个进程里面可 ...

随机推荐

  1. [学习笔记]修改关键跳无效且关键CALL又不存在的情况

    先用DI查下壳,VC++写的,无壳. 然后,打开软件看一下软件注册的情况 有弹窗,那载入OD看看能不能搜索到字符串 回到反汇编窗口,发现有两个JE都跳过了注册成功的代码 似乎很简单的样子,只要NOP掉 ...

  2. 冒泡 MS Azure 不便宜。。。

    一直在等 MS Azure 中国开卖, 最近有消息说正式商用了... 看看去,ok 发现官方网站 很奇葩.没有购买的地方 说毛线 啊 卧槽 欺骗感情还是吊人胃口? 好看了一下VM的价格,卧槽真不便宜. ...

  3. 《用Python解决数据结构与算法问题》在线阅读

    源于经典 数据结构作为计算机从业人员的必备基础,Java, c 之类的语言有很多这方面的书籍,Python 相对较少, 其中比较著名的一本 problem-solving-with-algorithm ...

  4. 【WebAPI】从零开始学会使用.NET Core WebAPI

    介绍 以后会慢慢总结在项目使用中或者学习到的webAPI相关的知识,在这里做记录. 我会从最开始的如何创建WebAPI项目到项目的后续知识一点一点的开始讲述记录. 通过简单有效的方式,让我们能够快速的 ...

  5. Android布局:宽度适应的横向跟随,防止挤掉重要视图

    不知道这样的布局该怎么描述,标题也是乱取的..直接上图吧 最近遇到了这样要求的布局: 1.上图中的“标题”长度不定,“状态”标签可能有多个并紧跟在标题右边,“属性”一直居右显示: 2.当“标题”过长, ...

  6. [android学习]__使用百度地图开放api编写地图定位app

    前言 在前面我已经记录关于如何使用百度地图api,以及如何配置相关的androidstudio配置了,接下来将记录如何使用百度地图api开发简单的地图定位apk,我将决定不定期持续更新本篇笔记,在每个 ...

  7. [深度学习工具]·极简安装Dlib人脸识别库

    [深度学习工具]·极简安装Dlib人脸识别库 Dlib介绍 Dlib是一个现代化的C ++工具箱,其中包含用于在C ++中创建复杂软件以解决实际问题的机器学习算法和工具.它广泛应用于工业界和学术界,包 ...

  8. iOS逆向开发(2):获取APP的类声明 | class-dump | dumpdecrypted

    之前介绍了怎么操作越狱的iOS设备(以下简称为手机),但简单操作手机并不是目标,小程的目标是手机上特定的APP,比如微信.淘宝.QQ音乐等等,因为小程可以从这些APP上拿到一些有用的信息或资源--比如 ...

  9. How Tomcat works — 三、tomcat启动(2)

    在了解了tomcat 的一些基本组件之后,学习启动过程就更容易理解了,因为启动过程就是启动各个组件. 目录 启动顺序 Bootstrap类 Catalina类 StandardServer类和Stan ...

  10. win32程序之窗口程序,以及消息机制

    win32程序值窗口程序,以及消息机制 一丶简介 通过上一讲.我们了解了窗口其实是绘制出来的.而且是不断绘制的过程. 所以窗口的本质是绘制. 但是我们现在看到的窗口程序.都可以点击关闭按钮. 使用鼠标 ...