android 广播机制小结

android的广播机制主要有两个角色,广播发送和接收者(BroadcastReceiver)。在android开发中广播的使用有很多。

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

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

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

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

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

比如一个很常见的GPS定位功能,如果需要获取实时经纬度,可以注册一个广播来接收。

如果按照广播的传递来分类,可以分为有序广播和无序广播。

有序广播:OrderedBroadcast

有序广播发出以后,同一时刻只能有一个广播接收器收到这条广播。优先级高的广播先接受到这条

广播。在当前广播接收器处理完自己的逻辑以后,可以执行两种动作:

  1.继续传递广播  2.将广播截断

无序广播:普通广播

无序广播会被注册了的相应的感兴趣(intent-filter匹配)接收,且顺序是无序的。如果发送广播时有相应的权限要求,BroadCastReceiver如果想要接收此广播,也需要有相应的权限。

无序广播的广播接收者不可以使用setResultData()方法和abortBroadcast()方法,如果使用了会报错。 但是可以使用getResultData()方法,虽然不报错,但是获取到的数据为null。但是在一种<u>特殊情况</u>下,getResultData()方法能取到无序广播传递的数据,下文会说明在什么情况下。

无序广播不可以被拦截,不可以被终止,不可以被修改,无序广播任何接收者只要匹配条件都可以接收到,无优先级问题。

如果想通过无序广播传递数据,则可以调用intent.putExtra方法传递, 接收者可通过intent.get...接收,不可通过getResultData接收。

无序广播的注册有两种方式

动态注册:

在代码中注册的广播,被称为动态注册。动态注册的广播,最后必须取消注册。这类广播,只有应用启

动了,才能接收到广播。

下面直接来看动态注册的核心代码

public class MainActivity extends AppCompatActivity {

//     决定广播接收器接收什么广播

    private IntentFilter intentFilter ;

    private NetworkChangeReceiver networkChangeReceiver ;

    private TextView txt_show ;

    private Button btn_isNetConnect ;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

//        获取控件实例

        txt_show = (TextView) findViewById(R.id.txt_show);

        btn_isNetConnect = (Button) findViewById(R.id.btn_isNetConnect);

//        在按钮监听器中注册广播

        btn_isNetConnect.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                intentFilter = new IntentFilter() ;

//       字符串 android.net.conn.CONNECTIVITY_CHANGE (这里属于系统级的广播要用指定的字符串,如果非系统广播,可以自定义字符串,也是广播接收的唯一标示)

//       表明广播接收器接收网络变化的广播

                intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");

//        网络变化广播接收器实例

                networkChangeReceiver = new NetworkChangeReceiver() ;

//        注册广播

//        别忘了,申明权限

                registerReceiver(networkChangeReceiver,intentFilter) ;//动态注册

            }

        });

    }

 

    /**

     * 动态注册的广播,必须在取消注册。

     * 我们在create(),方法创建的时候,注册了广播

     * 这里,我们在销毁活动中,取消注册,

     * 当然也可以在onPause()方法取消注册。

     */

    @Override

    protected void onDestroy() {

        super.onDestroy();

        unregisterReceiver(networkChangeReceiver);

    }

 

    /**

     * 用内部类实现一个网络变化广播接收器

     */

    class NetworkChangeReceiver extends BroadcastReceiver {

 

//        重写父类的onReceive()方法,接收到对应的广播的时候,就会回调这个方法

//        广播接收器的处理逻辑,就写此方法中

        @Override

        public void onReceive(Context context, Intent intent) {

//            获取网络管理服务类,就跟findViewById()方法一样

            ConnectivityManager connectivityManager =

                    (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

//            记住这样写。就好了。用到的时候,百度一下,边边角角,谁也记不清

            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo() ;

//          判断网络状态

            if(networkInfo != null && networkInfo.isAvailable()){

                txt_show.setText("当前网络可用");

            }else {

                txt_show.setText("当前网络不可用");

            }

        }

    }

}

静态注册:

相比于动态注册,静态注册比较简单,需要在主配置文件AndroidManifest.xml中注册。

代码:

 <receiver android:name="com.hua.bcreceiver.MyBroadcastReceiver" >
<intent-filter>
  <action android:name="android.intent.action.MY_BROADCAST" /> 
  <category android:name="android.intent.category.DEFAULT" /> 
 </intent-filter>
 </receiver>

发送普通广播:

//        自定义广播内容

       String broadcast = "allbet.broad.cn.broadcasttest.MY_BROADCAST" ;

//        绑定到Intent中

       Intent intent = new Intent(broadcast) ;

//        发送广播,调用Context的sendBroadcast()方法

       sendBroadcast(intent);

发送有序广播:

//         自定义广播内容

      String broadcast = "allbet.broad.cn.broadcasttest.MY_BROADCAST" ;

//         绑定到Intent中

      Intent intent = new Intent(broadcast) ;

//         发送有序广播

//         第一个参数依然是Intent

//         第二个参数是代表权限的字符串,这里写null就好了

       sendOrderedBroadcast(intent,null);

截断有序广播:

有序广播在传送中,是可以被截断,甚至可以修改广播携带的数据。

在receiver方法中使用abortBroadcast()方法进行截断。

本地广播:

之前我们发送的广播,都是系统全局广播,即我们发送的广播,能被系统的其他程序也接收到。这样是

很不安全的,因为,广播上说不定会携带着关键数据。或者,其他程序,不停的向我们发生垃圾广播。

本地广播是无法通过静态注册的广播接收者接收到

//       获取本地广播管理 实例

        localBroadcastManager = LocalBroadcastManager.getInstance(this);

 intentFilter = new IntentFilter("com.mjc.yydd") ;

        myLocalBr  = new MyLocalBr() ;

        localBroadcastManager.registerReceiver(myLocalBr,intentFilter);

        break;

注意事项:

1.不要在onReceiver方法中进行耗时操作,否则会ANR

2.在动态注册后一定要及时通过unrejester方法进行反注册,否则会造成内存泄露,也有可能会报too many broadcast receiver regist exception。值得一提的是,华为手机的android5.0和5.1版本,系统只提供500个广播接收者,也就是说当你连续注册且不解绑到501个广播时,就会抛出此异常,往上的版本可以上万个。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值