Android笔记(二十六) Android中的广播——BroadcastReceiver

什么是广播?

为了方便进行系统级别的消息通知,Android有一套类似广播的消息机制,每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收自己所关心的广播内容,这些广播可能是来自于系统,也可能是来自于其他程序。

广播可以分为两种类型:有序广播和标准广播

标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因为它们之间没有任何先后顺序可言,这种广播的效率会比较高,但同时也意味着它是无法被截断的

如上图所示,每个人都代表一个广播接收器,在广播发出之后,每个人(广播接收器)都会接收到这条广播

有序广播是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够接收到,当这个广播接收器中的逻辑执行完毕之后,广播才会继续传递。所以有序广播是有先后顺序的,优先级高的广播接收器可以先接受到广播消息,并且还可以阻断正在传递的广播,如果截断,后面的接收器就无法收到了

一个简单的示例演示一下:

MainActivity.java

package cn.lixyz.broadcasttest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //创建IntentFilter对象,并指定想要接收的广播
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        //创建广播接收器,并注册
        networkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消注册广播接收器
        unregisterReceiver(networkChangeReceiver);
    }

    //定义一个广播接收器
    class NetworkChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "网络环境发生变化啦!!", Toast.LENGTH_SHORT).show();
        }
    }
}

activity_main.xml默认即可,演示结果,按home键回到桌面(不要back),进入设置,关闭wifi

开启或关闭WIFI都会提示网络环境发生变化了,这里就是APP接收到了系统关闭/开启发出的广播,然后做出的反应。

如何发送广播?

发送广播只需要调用Context的sendBroadcast(Intent intent)方法即可,这条广播会启动intent参数所对应的BroadcastReceiver。

修改一下上面的代码

MainActivity.java

package cn.lixyz.broadcasttest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                EditText et = (EditText) findViewById(R.id.editText);
                String str = et.getText().toString();
                intent.setAction("BroadcastReceiver_Test");
                intent.putExtra("data", str);
                sendBroadcast(intent);
            }
        });
    }
}

MyReceiver.java

package cn.lixyz.broadcasttest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

/**
 * Created by LGB on 2015/9/11.
 */
public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收到的消息是: " + intent.getStringExtra("data"), Toast.LENGTH_SHORT).show();
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入您要广播的消息" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="发送广播" />

</LinearLayout>

AndroidManiFest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.lixyz.broadcasttest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="BroadcastReceiver_Test" />

            </intent-filter>
        </receiver>
    </application>

</manifest>

运行结果:

从AndroidManiFest中我们可见,MyReceiver监听BroadcastReceiver_Test这个acitivty,当符合该MyReceiver的广播出现时,MyReceiver的onReceiver()将会被触发。

在上面的代码中,使用的是sendBroadcast()方法来发送的广播,android提供了两种方法用于发送广播:

1)sendBroadcast()——用于发送普通广播

       2)sendOrderedBroadcast()——用于发送有序广播

对于有序广播而言,系统会根据接受者声明的优先级逐个执行接收器,在接收器接收到广播之后,可以选择继续传递,也可以终止广播,如果终止,那么后面的优先级的接收器就无法再接收到了,在接收到广播之后,接收者可以使用setResultExtras(Bundle)方法来将内容存入到Broadcast中,然后传给下一个接收者,下一个接收者可以通过Bundle bundle = getResultExtras(true)来接收上一个接收器存入的信息

看代码:

MainActivity.java

package cn.lixyz.broadcasttest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                EditText et = (EditText) findViewById(R.id.editText);
                String str = et.getText().toString();
                intent.putExtra("MainActivity", str);
                intent.setAction("BroadcastReceiver_Test");
                sendOrderedBroadcast(intent, null);
            }
        });
    }
}

MyFirstReceiver.java

package cn.lixyz.broadcasttest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

/**
 * Created by LGB on 2015/9/11.
 */
public class MyFirstReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String str = intent.getStringExtra("MainActivity");
        Bundle bundle = new Bundle();
        bundle.putString("MyFirstReceiver", "第一个广播接受者加入的消息");
        bundle.putString("MainActivity",intent.getStringExtra("MainActivity"));
        setResultExtras(bundle);
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入您要广播的消息" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="发送广播" />

</LinearLayout>

AndroidManiFest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.lixyz.broadcasttest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".MyFirstReceiver">
            <intent-filter android:priority="5">
                <action android:name="BroadcastReceiver_Test" />

            </intent-filter>
        </receiver>
        <receiver android:name=".MySecondReceiver">
            <intent-filter android:priority="4">
                <action android:name="BroadcastReceiver_Test" />
            </intent-filter>

        </receiver>
    </application>

</manifest>

MySecondReceiver.java

package cn.lixyz.broadcasttest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

/**
 * Created by LGB on 2015/9/11.
 */
public class MySecondReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        Bundle bundle = getResultExtras(true);
        String str1 = bundle.getString("MyFirstReceiver");
        String str2 = bundle.getString("MainActivity");

        Toast.makeText(context, "接收到的消息是: " + str1 + str2, Toast.LENGTH_SHORT).show();
    }
}

运行结果

时间: 2024-08-01 10:43:52

Android笔记(二十六) Android中的广播——BroadcastReceiver的相关文章

Android笔记二十六.Android异步任务处理(AsyncTask)

转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.引言 我们知道Android的UI线程主要负责处理用户的按键事件.用户触屏事件及屏幕绘图事件等,对于其他的操作尽量不要在UI线程中实现,因为这些操作很有可能会阻塞UI线程,比如一些耗时操作,会导致UI界面停止响应,从而降低了用户的体验.所以,为了避免UI线程失去响应的问题,Android建议将耗时操作放在新线程中完成,但新线程也可能需要动态更新UI组件:比如需要从网上获取一个网页,然后在Te

Android笔记二十四.Android基于回调的事件处理机制

如果说事件监听机制是一种委托式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源和事件监听器是统一的,或者说事件监听器完全消失了,当用户在GUI控件上激发某个事件时,控件自己特定的方法将会负责处理该事件. 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.View类的常见回调方法 为了使用回调机制来处理GUI控件上所发生的事件,需要为该组件提供对应的事件处理方法,而Java又是一种静态语言,我们无法为每个对象动态地添

Android笔记二十五.Android事件Handler消息传递机制

因为Android平台不同意Activity新启动的线程訪问该Activity里的界面控件.这样就会导致新启动的线程无法动态改变界面控件的属性值.但在实际Android应用开发中,尤其是涉及动画的游戏开发中,须要让新启动的线程周期性地改变界面控件的属性值,这就须要借助Handler的消息传递机制实现. 一.Handler类简单介绍 1.功能 Handler类主要有两个作用 (1)在新启动的线程中发送消息; (2)在主线程中获取消息.处理消息.即当须要界面发生变化的时候.在子线程中调用Handle

Android笔记二十八.Android绘图深度解析

Android绘图深度解析 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) Android绘图方法主要有两个步骤: (1)实现一个继承于View组件的类,并重写它的onDraw(Canavas canvas)方法; (2)显示定义的View子类,有两种方法:a.使用一个Activity来显示View子类,即 setContentView(new MyView(this, null));b.在Acitviy的布局文件中增加"包名.View子类&

Android之旅十六 android中各种资源的使用

android中各种资源的使用: 在android开发中,各种资源的合理使用应该在各自的xml中进行定义,以便重复使用; 字符串资源:strings.xml,xml中引用:@string/XXX,java代码中引用:R.string.XXX 样式资源:styles.xml,xml中引用:@style/XXX,java代码中引用:R.style.XXX 图片资源:colors.xml,xml中引用:@color/XXX,java代码中引用:R.color.XXX 尺寸资源:dimens.xml,x

【Unity 3D】学习笔记二十六:unity游戏脚本(六)

在3D游戏世界中,任何一个游戏对象在创建的时候都会附带Transform(变换)组件,并且该组件是无法删除的,也不应该删除.在unity中,Transform面板一共有3个属性: Position  (位置) Rotation(旋转) Scale(缩放) 这三个值都是用来调整游戏对象在游戏界面中的位置,状态等相关参数. Position  (位置) 任何一个游戏对象的三维坐标都保存在Vector3容器中,该容器记录对象在X轴,Y轴,Z轴的坐标.一旦Vector33容器中的坐标发生变化,那么Sce

angular学习笔记(二十六)-$http(4)-设置请求超时

本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错误 demo: html: <!DOCTYPE html> <html ng-app = 'HttpGet'> <head> <title>18.4 $http(2)</title> <meta charset="utf-8"

马哥学习笔记二十六——MySQL主从复制

配置MySQL复制基本步骤: 一.master 1.启用二进制日志 log-bin = master-bin log-bin-index = master-bin.index 2.选择一个惟一server-id server-id = {0-2^32} 3.创建具有复制权限的用户 REPLICATION SLAVE REPLICATION CLIENT 二.slave 1.启用中继日志 relay-log = relay-log relay-log-index = 2.选择一个惟一的server

Android学习笔记二十六.跨进程调用Service(AIDL Service)

跨进程调用Service(AIDL Service) 一.AIDL Service 1.什么是AIDL Service? AIDL,即Android Interface Definition Language.是Android用于定义远程接口,AIDL接口定义语言的语法比较简单,这种接口定义语言并不是真正的编程语言,它只是定义两个进程之间的通信接口.AIDL的语法与Java接口很相似,但存在如下几点差异: (1)AIDL定义接口的源代码必须以.aidl结尾; (2)AIDL接口中用到数据类型,除

Android笔记二十九. 一款简易画图板开发

一款简易画图板开发 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.画图板原理 1.直线效果 画图板表面上看起来可以随用户在触摸屏上自由的绘制任意图形,但是实际上当用户在触摸屏上移动时,两次拖动事件发生点的距离很小,多条极短的直线连接起来我们肉眼看起来就是直接了.在触摸屏绘制图形时,每条直线都是从上一次拖动事件发生点画到本次拖动事件的发生点,可以借助于Android提供的Path类来实现.然后,如果程序每次都是从上次拖动事件的发生点绘一条