Android广播机制(1)

简介

就是因为安卓中的每个应用程序都可以对自己感兴趣的广播进行注册,这样改程序就只会接收到自己所关心的广播内容,这些广播可能是来自于系统的,也可能是来自于其他应用程序的

发送广播和接收广播方式

发送广播:Intent
接收广播:广播接收器(Broadcast Receiver)

广播类型

标准广播:标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接受到这条广播消息。因此它们之间没有任何先后顺序可言,这种广播的效率比较高,但同时也意味着它是无法被截断的。
有序广播:有序广播则是一种同步执行广播,在广播发出之后,同一时刻只会有一个广播接收器能够接受到这条广播信息。但这个广播进入其中的逻辑执行完毕后,广播才会继续传递。所以此时的广播计数器是有先后顺序的,优先级高的广播接收器就可以先接受到广播消息,而且,并且前面的广播接收器还可以阶段正在传递的广播,这样后面的广播接收器就无法受到广播消息了。

接收系统广播

Android具有很多内置广播
注册广播的方式:

动态注册:在代码中注册
静态注册:在AndroidManifest.xml中注册


创建广播接收器

新建一个类继承自BroadcastReceiver->重写父类的onReceive()方法当有广播到来时,onReceive()方法就会执行,具体的逻辑可以在这个方法中处理。

动态注册监听网络变化

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=new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//想监听什么广播就添加相应的action
        networkChangeReceiver=new NetworkChangeReceiver();//广播接收器
        registerReceiver(networkChangeReceiver,intentFilter);//注册
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);//动态注册的广播必须取消注册
    }
    //广播接收器继承BroadcastReceiver这个类,每次接收到广播会调用onReceive()方法
    class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
                Toast.makeText(context,"network changes",Toast.LENGTH_SHORT).show();
        }
    }
}

步骤

1.注册广播:创建IntentFilter对象->添加广播对应的action
2.新建广播接收器继承自Broadcast类重写onReceive方法
3.registerReceiver注册广播,将IntentFilter对象和广播接收器实例对象传进去(这样广播和广播接收器的逻辑就绑定在一起了)
4.动态注册的广播一定记得取消注册unregisterReceiver
**注:Android系统为了保护用户设备的安全和隐私做了严格的规定,如果程序需要进行一些对于用户来说比较敏感的操作,就必须在配置文件中声明权限才可以,否则程序将会直接崩溃,比如这里访问系统的网络状态就是需要声明权限的。打开AndroidManifest.xml文件,加入以下代码,才可以访问系统网络状态:

<manifest xmlns:andro
    package="com.example.broadcasttest">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    ...
</manifest>

优化

告诉用户当前网络状态是可用还是不可用。修改MainActivity中的代码:

public class MainActivity extends AppCompatActivity {
 ...
 class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connectivityManager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
            if(networkInfo!=null&&networkInfo.isAvailable()){
                Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show();
            }
        }
  }
}

静态注册实现开机启动

动态注册广播接收器可以*的控制注册与注销,在灵活性方面有很大的优势,但是它也存在着一个缺点即必须要在程序启动之后才能接受到广播,因为注册的逻辑写在onCreate方法中的

步骤

1.创建广播接收器的快捷方式:右击com.example.broadcasttest包->New->Other->Broadcast Receive.出现以下窗口后,Exported表示是否允许这个广播接收器接收本程序之外的广播,Enable表示是否启用这个广播接收器.
Android广播机制(1)
2.然后修改BootCompleteReceiver中的代码:

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

**注:静态注册的广播一定要在AndroidManifest.xml中注册(快捷方式已经帮我们完成了)标签,如下展示:

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

注意

不要在onReceive()方法中添加过多的逻辑或者进行任何耗时的操作,在广播接收器中是不允许开启线程的,当onReceive()运行较长时间却没有结束时,程序就会保报错。因此,广播接收器更多的是扮演一种打开其他程序组件的角色,比如创建一条状态栏通知,或者启动一个服务。