广播的动态注册和静态注册以及系统广播的使用!

广播的动态注册和静态注册以及系统广播的使用!


作者:燕潇洒

导读:前面在说使用广播实现进程间的被动通信的时候,没有考虑到大家是否懂得如何发送广播,在http://blog.csdn.net/yanxiaosa/article/details/59116262这篇博客中,只是稍微说一下广播的简单发送和接收,今天,来给大家说一下,广播的注册(动态和静态)、发送和接收;


Android广播机制概述

Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广

播接收者(广播接收器)。广播作为Android组件间的通信方式,可以使用的场景如下:

1.同一app内部的不同组件之间的消息通信(单个进程);

2.不同app之间的组件之间消息通信;

3.Android系统在特定情况下与App之间的消息通信。

4.同一app内部的同一组件内的消息通信(单个或多个线程之间);

5.同一app具有多个进程的不同组件之间的消息通信;

自定义BroadcastReceiver

自定义广播接收器需要继承基类BroadcastReceivre,并实现抽象方法onReceive(context,

intent)方法。广播接收器接收到相应广播后,会自动回到onReceive(..)方法。默认情况下,广播接

收器也是运行在UI线程,因此,onReceive方法中不能执行太耗时的操作。否则将因此ANR(我在

onReceive方法中sleep10秒并没有出现ANR,但并不说明可以进行耗时操作,具体以官方文档为

主),onReceive方法中都会涉及到与其他组件之间的交互,如发送Notification、启动service等。

下面就是一个简单的广播接收者的例子:

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if("SendNotify".equals(intent.getAction())){
            Toast.makeText(context, "收到广播", Toast.LENGTH_SHORT).show();
        }else if(Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())){//接受系统广播
            Toast.makeText(context, "充电器连接了", Toast.LENGTH_SHORT).show();
        }
    }
}

BroadcastReceiver的注册类型

BroadcastReceiver总体上可以分为两种注册类型:静态注册和动态注册。

静态注册

所谓静态注册就是直接在清单文件(AndroidManifest)中进行注册:

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

        <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=".MyReceiver">
                <intent-filter>
                    <action android:name="SendNotify"></action>
                </intent-filter>
            </receiver> 

        </application>

</manifest>

上面的标签就是静态注册广播,需要将其写在标签之内,它是与标签同等级的.在标签中需要注意的有:

  • android:exported ——-此broadcastReceiver能否接收其他App的发出的广播,这个属性默认值有点意思,其默认值是由receiver中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。(同样的,activity/service中的此属性默认值一样遵循此规则)同时,需要注意的是,这个值的设定是以”application”或者”程序唯一标识”为界的,而非进程为界(一个应用中可能含有多个进程);

  • android:name ——是broadcastReceiver类名;

  • android:permission—-如果设置,那么具有相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收;

  • android:process—–broadcastReceiver运行所处的进程。默认为app的进程。可以指定独立的进程(Android四大基本组件都可以通过此属性指定自己的独立进程)

动态注册

动态注册时,无须在清单文件(AndroidManifest)中注册组件。直接在代码中通过调用Context的registerReceiver函数,可以在程序中动态注册BroadcastReceiver。registerReceiver的定义形式如下:

registerReceiver(BroadcastReceiver receiver, IntentFilter filter);

registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler);

经常使用的写法示例如下:

public class BroadCastReceiverActivity extends Activity {

    /**
     * 广播接收者
     */
    private MyReceiver myReceiver;

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

    /**
     * 动态注册广播
     */
    public void initBroadCast(){
        myReceiver = new MyReceiver();
        IntentFilter filter = new IntentFilter("SendNotify");
        registerReceiver(myReceiver,filter);
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(myReceiver);
        super.onDestroy();
    }
}

注:当此Activity实例化时,会动态将MyReceiver注册到系统中。当此Activity销毁时,动态注册的MyReceiver将不再接收到相应的广播,需要我们在onDestroy方法中调用unregisterReceiver方法,将不再使用的广播取消注册。

动态注册的案例

以上面的代码为例,我们在这里完善一下,在一个新的activity中,我们声明了一个按钮,然后再activity中初始化这个按钮,给按钮一个点击事件,在点击事件中发送一个广播:

public class BroadCastReceiverActivity extends Activity {
        /**
         * 发送广播的按钮
         */
        private Button btn_send_notify;
        /**
         * 广播接收者
         */
        private MyReceiver myReceiver;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_broad_cast_receiver);
            initBroadCast();
            btn_send_notify = (Button) findViewById(R.id.btn_send_notify);
            btn_send_notify.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //指定广播的action(频道)
                    Intent intent = new Intent("SendNotify");
                    //广播附带的消息内容
                    intent.putExtra("you","我发了一个广播");
                    sendBroadcast(intent);
                }
            });
        }

        /**
         * 动态注册广播
         */
        public void initBroadCast(){
            myReceiver = new MyReceiver();
            IntentFilter filter = new IntentFilter("SendNotify");
            registerReceiver(myReceiver,filter);
        }
        @Override
        protected void onDestroy() {
            unregisterReceiver(myReceiver);
            super.onDestroy();
        }
}

现在已经发送了广播,那么,谁来接收呢?我们来继承BroadcastReceiver自定义自己的接受者:


public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //根据action过滤广播内容
        if("SendNotify".equals(intent.getAction())){
            Toast.makeText(context, "收到广播"+intent.getStringExtra("you"), Toast.LENGTH_SHORT).show();
        }
    }
}

到此结束,一个动态广播就可以使用了,我们运行看效果:

静态注册

依然以上面的代码为例:我们把动态注册换成静态注册,打开清单文键,在application节点中加上节点:

    <receiver android:name=".MyReceiver">
        <intent-filter>
            <action android:name="SendNotify"></action>
        </intent-filter>
    </receiver>

再次运行程序,这里就不再加图片了,因为效果和上面的图片一模一样.

系统广播

为了避免繁琐,我们依旧使用动态注册的代码。android系统为我们提供了很多系统的广播,例如:低电量时的提醒,关机提醒等等,我们在这里使用usb连接手机时发送广播,我们使用静态注册的方式来实现,在上面的静态注册中,我们依旧使用MyReceiver作为接受者,在清单文件中,我们把节点中的name改成系统广播的名称:

    <receiver android:name=".reciver.MyReceiver">
        <intent-filter>
            <action android:name="android.intent.action.ACTION_POWER_CONNECTED"></action>
        </intent-filter>
    </receiver>

然后在广播接受者中过滤这个系统广播:

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if("SendNotify".equals(intent.getAction())){
            Toast.makeText(context, "收到广播---->>>>"+intent.getStringExtra("you"), Toast.LENGTH_SHORT).show();
        }else if(Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())){//接受系统广播
            Toast.makeText(context, "充电器连接了", Toast.LENGTH_SHORT).show();
        }
    }
}

这里我们并没有去掉上一个广播的过滤,所以我们两个广播都会收到,再次运行,看效果:

这里写图片描述

我们在插上数据线的时候就会触发这个广播…

广播的基本使用到这里就结束了,我们讲了广播的动态和静态注册,还有系统广播的使用,在这篇http://blog.csdn.net/yanxiaosa/article/details/59116262博文中,我们讲了使用广播实现两个app之间的通信,如果你看完了广播的基本使用,就去看看使用广播实现进程间的通信这篇文章了.
http://blog.csdn.net/yanxiaosa/article/details/59116262

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值