学习笔记:四大组件之Broadcast Receiver理解

一、广播定义

1.Broadcast(广播)

它是一种广泛运用于应用程序之间传输信息的机制。


2.BroadcastReceiver(广播接收器)

它是对发送出来的广播进行过滤接收并响应的一类组件,用来接收来自系统和应用程序中的广播。

3.用途:业务逻辑在BroadcastReceiver中的onReceive()方法中实现,一般用来启动一个Activity、Service或者标题通知

  - 当开机完成后,系统会发出一条广播;
  - 当网络状态发生变化时,系统会发出一条广播;
  - 当电池电量发生改变时,系统会发出一条广播;
  - 等等

4.使用方法:


  - 发送:将信息装入一个Intent对象intent(如Action、Category),然后调用如下方法之一发送广播:
           sendBroadcast(intent)和sendOrderBroadcast(intent, null)

  - 接收:当Intent发送以后,所有已经注册的BroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent匹配,若匹配则调用BroadcastReceiver的onReceive()方法,该方法需要在定义BroadcastReceiver对象时去复写。

5.注意

  - BroadcastReceiver生命周期大概只有10秒,不能在其中执行耗时操作

  - 不能使用子线程,因为子线程可能还未执行完,BroadcastReceiver生命周期已经结束,那么子线程也会被杀
    死

  - 可以在BroadcastReceiver的onReceive()方法中通过发送Intent给Service,由Service来完成耗时操作

6.注册方式:

  - 动态注册:在java代码中完成注册,一般在Activity的onCreate()中调用registerReceiver(mReceiver,mIntentFilter)注册广播接收器,在onDestroy()中调用unregusterReceiver(mReceiver)来注销广播。动态注册的广播接收器只能在程序启动后,才能接收广播,因为它在onCreate(0方法中注册的。典型的不能接收开机广播,因为刚开机 时,该程序还未启动,才 能接收广播;

  - 静态注册:在AndroidManifest.xml中完成注册,添加<receiver />标签。静态注册的广播接收器不需要运行该程序也会收到相应的广播。可以在<intent-filter>标签中添加优先级来优先监听有序广播。



7.广播的种类:

  - 普通广播:异步、无序、所有BroadcastReceiver都可以监听;调用sendBroadcast(intent)发送标准广播

  - 有序广播:同步、按照接收者的优先级顺序接收广播、可以被前面的BroadcastReceiver截断,或被篡改后继
   续传递给下一个接收器;调用sendOrderedBroadcast(intent, null)来发送有序广播。接收广播方法,不      区分有序还是标准广播。



8.广播接收器的作用域

 - 系统广播:可以用来接收本程序或者其它应用程序(系统)的广播,包括普通广播和有序广播
 
 - 本地广播:只能够接收来自本程序内部发出的广播,避免出现关键性数据泄露,造成安全性问题。只能动态注    册,需要用到LocalBroadcastManager来管理本地广播。

   发送本地广播: l ocalBroadcastManager.sendBroadcast(intent);
   注册本地广 播: localBroadcastManager.registerReceiver(localReceiver,intentFilter) ;
   注销本地广播:l ocalBroadcastManager.unregisterReceiver(localReceiver)



二、参考代码


本文定义了三个BroadcastReceiver,分别是如下:
1.静态注册的MyBroadcastReceiver,用来测试发送携带数据的普通/有序广播,并且能够接收到广播取出数据;
2.静态注册的BootCompleteReceiver,用来测试接收手机开机时系统发出的开机广播;
3.动态注册的NetworkStateChangeReceiver,用来测试当手机出现网络状态变化时,判断当前网络可用或不可用。


MyBroadcastReceiver
package com.steven.dynamicbroadcasttest;

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

/**
 * Created by Steven on 2016/9/19.
 */
//静态注册的一个自定义广播,监听发送的标准广播:MY_BROADCAST
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String s = intent.getStringExtra("test");
        Toast.makeText(context, "I receive a MyBroadcastReceiver,传递过来的数据是:" + s, Toast.LENGTH_SHORT).show();
        Log.d("Steven", "收到自定义广播的数据是:" + s);
    }
}




BootCompleteReceiver

package com.steven.dynamicbroadcasttest;

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

/**
 * Created by Steven on 2016/9/19.
 */
//静态注册的一个系统的监听开机广播,在程序未运行起来的时候也能监听
//An (non-static) inner class cannot be instantiated by Android via the AndroidManifest.xml
public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("steven", "**** BootCompleteReceiver ****");
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
    }
}


MainActivity

package com.steven.dynamicbroadcasttest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private NetworkStateChangeReceiver receiver;
    private Button btn_send_broadcast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_send_broadcast = (Button) findViewById(R.id.btn_send_broadcast);

        //2. 生成一个BroadcastReceiver
        receiver = new NetworkStateChangeReceiver();

        //3. 生成IntentFilter对象,并添加action,指定要监听的广播类型:网络状态变化
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");

        //4 .注册一个广播
        registerReceiver(receiver, intentFilter);

        //发送一个自定义标准/有序广播MY_BROADCAST
        btn_send_broadcast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.steven.dynamicbroadcasttest.MY_BROADCAST");
                intent.putExtra("test", "MY_BROADCAST");             //intent此时可以携带数据一起发送
                //sendBroadcast(intent);                             //发送标准广播
                sendOrderedBroadcast(intent, null);                  //发送有序广播
            }
        });
    }

    //5. 动态定义的广播,一定要在退出程序时,注销广播
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    // 1.动态定义一个BroadcastReceiver,复写onReceive()抽象方法,实现收到广播的具体逻辑业务:网络变化时判断可用还是不可用
    public class NetworkStateChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            //Toast.makeText(context, "Network State Changed", Toast.LENGTH_SHORT).show();
            //通过Activity中的getSystemService()方法获得一个用于管理网络连接的ConnectivityManager实例
            ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            //通过调用它的getActiveNetworkInfo(),获得NetworkInfo实例
            NetworkInfo info = manager.getActiveNetworkInfo();

            //网络可用状态下
            if (info != null && info.isAvailable()) {
                Toast.makeText(context, "Network is available", Toast.LENGTH_SHORT).show();
            //网络不可用
            } else {
                Toast.makeText(context, "Network is not available", Toast.LENGTH_SHORT).show();
            }
        }
    }
}


AndroidManifest.xml:静态注册的广播接收器需要在该文件注册,同时监听开机广播和网络状态需要注册系统权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.steven.dynamicbroadcasttest" >

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

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

        <receiver android:name=".BootCompleteReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

        <receiver android:name=".MyBroadcastReceiver">
            <intent-filter android:priority="100">
                <action android:name="com.steven.dynamicbroadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

三、Demo实例




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值