您的位置:首页 > 移动开发 > Android开发

Android broadcast

2015-11-02 17:57 405 查看
个人原创,请勿copy,转发请注明出处http://blog.csdn.net/zenmela2011/article/details/49582997

Android广播分为标准广播和有序广播两种。

标准广播是一种完全异步执行的广播,在广播发出后,所有广播接收器都会同一时间收到这条广播消息,因此他们之间没有任何先后顺序。这种广播效率比较高,但是它是无法被截获的。

有序广播是一种同步执行的广播,在广播发出后,同一时间只有一个广播接收器能收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以有序广播的广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。

要想接收某个广播,首先需要注册对应该广播的广播接收器。注册广播的方法有两种,在代码中注册(动态注册)和在Androidmanifest.xml中注册(静态注册)。

创建广播接收器,需要新建一个类,继承BroadcastReceiver,并重写父类的onReceive()方法。这样当有广播到来时,onReceive()方法就会得到执行,具体的逻辑就可以在这个方法中处理。

一、动态注册

①接收系统广播(不需要手动发送广播,系统会自动发送)

1.新建一个广播接收器,在onReceive()方法中写入收到广播后需要执行的逻辑。

class NetworkChangeReceiver extends BroadcastReceiver{

//有广播到来时,自行执行该方法
@Override
public void onReceive(Context arg0, Intent arg1) {
Toast.makeText(MainActivity.this, "收到广播啦!", Toast.LENGTH_LONG).show();

}

}


2.在活动中,我们的广播接收器想要监听什么广播,先添加相应的action

IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");


当网络状态发生变化是,系统会自动发出一条值为android.net.conn.CONNECTIVITY_CHANGE的广播

    3.初始化自定义的广播接收器

NetworkChangeReceiver networkChangeReceiver=new NetworkChangeReceiver();


   4.用registerReceiver()方法注册监听,传入监听器和需要监听的action。 

registerReceiver(networkChangeReceiver,intentFilter);


这样NetworkChangeReceiver就会收到所有值为android.net.conn.CONNECTIVITY_CHANGE的广播

5.在onDestroy()方法中用unregisterReceiver()取消注册

unregisterReceiver(networkChangeReceiver);


实例:

public class MainActivity extends Activity {

	NetworkChangeReceiver networkChangeReceiver;

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

/**
* 我们的广播接收器想要监听什么广播,就在这里添加相应的action
* 当网络状态发生变化是,系统会自动发出一条值为android.net.conn.CONNECTIVITY_CHANGE的广播
*/
IntentFilter intentFilter=new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//初始化自定义的广播接收器
networkChangeReceiver=new NetworkChangeReceiver();
/**
* 用registerReceiver()方法注册监听,传入监听器和需要监听的action
* 这样NetworkChangeReceiver就会收到所有值为android.net.conn.CONNECTIVITY_CHANGE的广播
*/
registerReceiver(networkChangeReceiver,intentFilter);

}

//取消注册
@Override
protected void onDestroy() {
super.onDestroy();
this.unregisterReceiver(networkChangeReceiver);
}

class NetworkChangeReceiver extends BroadcastReceiver{

//有广播到来时,自行执行该方法
@Override
public void onReceive(Context arg0, Intent arg1) {
ConnectivityManager connectivityManager=(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isAvailable()){
Toast.makeText(MainActivity.this, "网络可用!", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MainActivity.this, "无网络连接!", Toast.LENGTH_LONG).show();
}
}

}
}
在AndroidManifest.xml中添加INTERNET和ACCESS_NETWORK_STATE权限。
动态注册的广播接收器一定都要取消注册才行。

②接收自定义广播(需要手动用sendBroadcast()方法发送广播)

1.首先自定义一个Action

private static final String MY_ACTION = "com.fang.test.SENDBROADCAST";


2.用sendBroadcast()方法发送广播

//构建一个intent对象,传入要发送的广播的值,还可以在intent中携带一些数据传递给广播接收器,然后用s endBroadcast()方法把广播发送出去
Intent intent=new Intent(MY_ACTION);
intent.putExtra("sendBroadcast", "点击了按钮,发出广播了");
sendBroadcast(intent);


  3.新建一个广播接收器,在onReceive()方法中写入收到广播后需要执行的逻辑。

class NetworkChangeReceiver extends BroadcastReceiver{

//有广播到来时,自行执行该方法
@Override
public void onReceive(Context arg0, Intent intent) {
String extra=intent.getStringExtra("sendBroadcast");//接收intent携带过来的数据
Toast.makeText(MainActivity.this, extra, Toast.LENGTH_LONG).show();
}
}


4.用registerReceiver()方法注册广播。

//由于我们要接收自定义为MY_ACTION的广播,因此在intentFilter中添加该action
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(MY_ACTION);
//初始化自定义的广播接收器
myReceiver=new MyReceiver();
/**
* 用registerReceiver()方法注册监听,传入监听器和需要监听的action
*/
registerReceiver(myReceiver,intentFilter);


5.在onDestroy()方法中用unregisterReceiver()取消注册

unregisterReceiver(myReceiver);


实例:

public class MainActivity extends Activity {
//自定义一个广播Action
private static final String MY_ACTION = "com.fang.test.SENDBROADCAST";
MyReceiver myReceiver;

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

//点击按钮,发送广播
findViewById(R.id.btn_send_broadcast).setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
//构建一个intent对象,传入要发送的广播的值,然后用sendBroadcast()方法把广播发送出去
Intent intent=new Intent(MY_ACTION);
intent.putExtra("sendBroadcast", "点击了按钮,发出广播了");
sendBroadcast(intent);

}

});
/**
* 我们的广播接收器想要监听什么广播,就在这里添加相应的action
*/
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(MY_ACTION);
//初始化自定义的广播接收器
c6fc

myReceiver=new MyReceiver();
/**
* 用registerReceiver()方法注册监听,传入监听器和需要监听的action
*/
registerReceiver(myReceiver,intentFilter);

}

//取消注册
@Override
protected void onDestroy() {
super.onDestroy();
this.unregisterReceiver(myReceiver);
}

class MyReceiver extends BroadcastReceiver{

//有广播到来时,自行执行该方法
@Override
public void onReceive(Context arg0, Intent intent) {
String extra=intent.getStringExtra("sendBroadcast");
Toast.makeText(MainActivity.this, extra, Toast.LENGTH_LONG).show();
}

}
}
二、静态注册

动态注册的广播接收器可以自由的控制注册与注销,在灵活性方面有很大的优势,但是它存在一个缺点,就是必须要在程序启动之后才能接受到广播,因为注册的逻辑卸载onCreate()方法中。而静态注册则可以让程序在未启动的情况下就能接收到广播。
①接收系统广播。以接收开机广播为例:
1.新建一个广播接收器类,在onReceive()方法中写入收到广播后需要执行的逻辑。

package com.example.androidtest;
public class BootBroadcast extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context, "boot", Toast.LENGTH_LONG).show();

}
}


2.在AndroidManifest.xml中注册广播,在intent-filter中加入想要接收的广播。
android系统启动完成后会发出一条值为android.intent.action.BOOT_COMPLETED的广播。

<receiver android:name="com.example.androidtest.BootBroadcast">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>


同时添加ACCESS_NETWORK_STATE和RECEIVE_BOOT_COMPLETED权限。
②接收自定义广播。
1、新建一个广播接收器类,在onReceive()方法中写入收到广播后需要执行的逻辑。

package com.example.androidtest;
public class MyBroadcast extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context, "boot", Toast.LENGTH_LONG).show();
}
}


2、在活动中发送自定义的广播。

Intent intent=new Intent("com.fang.mybroadcast");
sendBroadcast(intent);


3、在AndroidManifest.xml中注册广播,在intent-filter中加入想要接收的广播。

<receiver android:name="com.example.androidtest.MyBroadcast">
<intent-filter >
<action android:name="com.fang.mybroadcast"/>
</intent-filter>
</receiver>


这里让MyBroadcast接收一条值为com.fang.mybroadcast的广播,因此当发送广播时,我们就在MyBroadcast中收到了。

使用广播时注意:

1.不要在onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的,当在onReceive()方法中运行了较长时间而没有结束时,程序就会报错。

2、普通广播是一种可以跨进程的通信方式,因此在一个应用程序内发出的广播,其他的应用程序也是可以接收到的,只要这些应用程序都注册了这个广播的接收器即可。



三、注册本地广播

前面发送和接收的都属于系统全局广播,即发出的广播可以被其他任何应用程序接收到,并且我们也可以接收到来自其他任何应用程序的广播。这样就很容易引起安全性的问题,比如我们发送的一些携带关键性数据的广播有可能被其他的应用程序截获,或者其他应用程序不停地向我们的广播接收器发送各种垃圾广播。

为了能够简单地解决广播的安全性问题,android引入了一套本地广播机制,只用该机制发出的广播只能够在应用程序内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就不存在了。

使用本地广播,主要是利用LocalBroadcastManager来对广播进行管理,并提供了发送和注册广播接收器的方法。

1、在活动中获得LocalBroadcastManager实例

LocalBroadcastManager localBroadcastmanager = LocalBroadcastManager.getInstance(this);
2、在活动中利用localBroadcastManager发送本地本地广播
Intent intent = new Intent("cong.fang.mylocalbroadcast");
localBroadcastManager.sendBroadcast(intent);//发送本地广播
3、在活动中注册本地广播监听器
//需要监听的action
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.fang.mylocalbroadcast");
//初始化自定义的本地广播接收器
MyLocalReceiver myLocalReceiver = new MyLocalReceiver();
//注册本地广播接收器
localBroadcastManager.registerReceiver(myLocalReceiver,intentFilter);
4、在活动中新建一个广播接收器类
class MyLocalReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context, "接收到本地广播了", Toast.LENGTH_LONG).show();

}

}
5、在OnDestroy()方法中取消注册广播
@override
protected void onDestroy(){
localBroadcastManager.unRegisterReceiver(myLocalReceiver);//取消注册
}注意:本地广播是无法通过静态注册的方式来接收的。其实这也完全可以理解,因为静态注册主要就是为了让程序在未启动的情况下也能接收到广播,而发送本地广播时,我们的应用程序肯定是已经启动了,因此也完全不需要使用惊天注册的功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: