广播机制

Android 中的广播主要分为两种类型:标准广播和有序广播、

标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息。他们之间没有任何先后顺序可言。无法被截断。

有序广播则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。广播接收器是有先后顺序的,优先级搞得广播接收器就可以先收到广播消息,还可以截断正在传递的广播。



动态注册监听网络变化
       广播接收器可以自由地对自己感兴趣的广播进行注册,这样广播接收器就能够收到该广播,并在内部处理相应的逻辑。注册广播的方式一般有两种:
动态注册和在AndroidManifest.xml中注册,如何创建一个广播接收器呢?

1.继承自 BroadcastReceiver
2.重写父类的onReceive()方法



package com.example.chenac.broadcasttest;

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.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {

   
private IntentFilter intentFilter ;
   
private  NetworkChangeReceiver newworkChangeReceiver ;


   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super .onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main );
       
//
        intentFilter=new IntentFilter();
//当网络状态发生时,系统发出的正是一条值为
       //android.net.conn. CONNECTIVITY_ CHANG的广播, 也就是说我们的广播接收器                        //想要监听什么广播,就在这里添加相应的 action 就行了
        intentFilter .addAction( "android.net.conn.CONNECTIVITY_CHANGE" );
    //创建了一个 NetworkChangeReceiver 的实例,然后调用registerReceiver()
方法进行注册,将 NetworkChangeReceiver 的实例和IntentFilter 的实例都传了进去,这样
NetworkChangeReceiver 就会收到所有值为android.net.conn.CONNECTIVITY_CHANGE 的广
播,也就实现了监听网络变化的功能。
        newworkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(
newworkChangeReceiver , intentFilter );

    }

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


   
class NetworkChangeReceiver extends BroadcastReceiver{
       
@Override
       
public void onReceive(Context context,Intent intent){
            ConnectivityManager connectivityManager=(ConnectivityManager)getSystemService(Context.
CONNECTIVITY_SERVICE ); //getSystemService()方法得到了ConnectivityManager 的
            //   实例,这是一个系统服务类,专门用于管理网络连接的
            Toast. makeText(context,"newwork changes",Toast. LENGTH_SHORT).show();


//
//调用它的 getActiveNetworkInfo()
方法可以得到 NetworkInfo 的实例,接着调用NetworkInfo isAvailable()方法,就可以判断
出当前是否有网络了,最后我们还是通过 Toast 的方式对用户进行提示。
            NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
           
if (networkInfo != null && networkInfo.isAvailable()){
                Toast.
makeText(context,
"network is available" ,Toast. LENGTH_SHORT ).show();
            }

        }
    }
}


注意:
最后要记得,动态注册的广播接收器一定都要取消注册才行,这里我们是在 onDestroy()
方法中通过调用 unregisterReceiver()方法来实现的。

这里有非常重要的一点需要说明, Android 系统为了保证应用程序的安全性做了
规定,如果程序需要访问一些系统的关键性信息,必须在配置文件中声明权限才可以,否则
程序将会直接崩溃, 比如这里查询系统的网络状态就是需要声明权限的。打开
AndroidManifest.xml 文件,在里面加入如下权限就可以查询系统网络状态了:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>





静态注册实现开机启动
动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大的优势,但是
它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在
onCreate() 方法中的。那么有没有什么办法可以让程序在未启动的情况下就能接收到广播
呢?这就需要使用静态注册的方式了。

public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
}
}

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

</receiver>

<application> 标签内出现了一个新的标签 <receiver> ,所有静态注册的广播接收器
都是在这里进行注册的。它的用法其实和 <activity> 标签非常相似,首先通过 android:name
来指定具体注册哪一个广播接收器,然后在 <intent-filter> 标签里加入想要接收的广播就行了,
由于 Android 系统启动完成后会发出一条值为 android.intent.action.BOOT_COMPLETED 的广
播,因此我们在这里添加了相应的 action
监听系统开机广播也是需要声明权限的,可以看到,我们使用 <uses-permission>
标签又加入了一条 android.permission.RECEIVE_BOOT_COMPLETED 权限。


发送自定义广播
发送标准广播
     
 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0" >
……
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
……
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="com.example.broadcasttest. MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>


 

public class MainActivity extends Activity {
……
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.
MY_BROADCAST");
sendBroadcast(intent);
}
});
……
}

发送标准广播和发送有序广播的却别
发送标准广播使用的是:sendBroadcast(intent);
发送有序广播使用的是:sendOrderBroadcast(intent,null);   //第二个参数传入的是权限

如何设定广播接收器的先后顺序呢?当然是在注册的时候进行设定的了,修改
AndroidManifest.xml 中的代码:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0" >
<application
android:allowBackup="true" 3
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".MyBroadcastReceiver">
<intent-filter android:priority="100" >
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>
</manifest>


如果在 onReceive() 方法中调用了 abortBroadcast() 方法,就表示将这条广播截断,后面的
广播接收器将无法再接收到这条广播。现在重新运行程序,并点击一下 Send Broadcast 按钮,
你会发现, 只有 MyBroadcastReceiver 中的 Toast 信息能够弹出, 说明这条广播经过
MyBroadcastReceiver 之后确实是终止传递了。

本地广播

前面我们发送和接收的广播全部都是属于系统全局广播,即发出的广播可以被其他任何
的任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播。这样就很容
易会引起安全性的问题。

主要就是使用了一个 LocalBroadcastManager 来对广播进行 管理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值