Android之BroadcastReceiver基础学习

来源:互联网 发布:自学数学软件 编辑:程序博客网 时间:2024/04/29 23:43

1.Android广播机制的理解

在 Android 里面有各种各样的广播,比如电池的使用状态,电话的接收和短信的接收都会产生一个广播,应用程序开发者也可以监听这些广播并做出程序逻辑的处理。

广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。(举个简单的例子,当你在开车时收听交通道路广播,它会告诉你某些路段的路况如何,比如堵车等等,但它不管你是否接受到没有,也许你车上的接收器坏掉了没接收到,也不管你是要继续朝堵车路段开去还是绕过堵车路段,它依然会继续朝向大众发送交通道路广播。)

Android 中有各式各样的广播,各种广播在Android 系统中运行,当系统或应用程序运行时便会向 Android系统 注册各种广播,Android 接收到广播会便会判断哪种广播对应哪种事件,然后向不同需求事件的应用程序注册事件,不同的广播可能处理不同的事件也可能处理相同的广播事件,这时就需要Android 系统为我们做筛选。下面举例理解这段话:

生活中广播电台发送广播时我们怎么收听呢?当然是通过收音机等设备也就是BroadcastReceiver,没有BroadcastReceiver的程序是收听不到广播的。有了收音机BroadcastReceiver,有那么多的频道,我们要自己调频调到自己要收听的广播频道去,在Android系统中通过定义广播的类别来实现。

需要注意的是,世界中接收同一个标记信号的广播存在个,也许广播A和广播B监听的是同一个信号  这是不冲突的。但究竟是广播A先接收到信号还是广播B先接收到,这就涉及到了有序广播,和有序广播相对应的是普通广播。  

 普通广播: 普通广播可以让所有的广播君一起接收到信号(逻辑上),如果有10个广播君,那么是个都可以接收到,无法停止信号的传播。  

     有序广播:有序广播传播的方式如同传递,比如有10个广播,A传到B,B再到C,以此类推,如果传到D后,D想终止信号的传播,那么D以后  的广播君就接收不到信号了。虽然这10个广播都在等待接收同一个信号,但在D这里,就有权利终止信号的传输。有序广播还有一个特点,广播可以将自己的内容传给下一位唯一需要确定的是,到底是广播A先接收到还是广播B先接收到,这就需要在广播们在注册时,考虑到”优先级“的问题了。

在配置文件的每个receiver中的intent-filter标签中添加一个属性android:priority="100",数字越高  优先级越大。  

<receiver android:name=".MyBroadcastReceiver">  

      <intent-filter android:priority="11">  

            <action android:name="wuchen.broadcastReceiver.MY_RECEIVER"/>  

        </intent-filter>  

    </receiver>  

    <receiver android:name=".MyBroadcastReceiver_B" >  

        <intent-filter android:priority="10">  

            <action android:name="wuchen.broadcastReceiver.MY_RECEIVER"/>  

        </intent-filter>  

</receiver>  

 

注意:动态注册的广播优先级高于静态注册的广播。

2.使用BroadcastReceiver的步骤

     1.编写类继承BroadcastReceiver,覆写onReceiver()方法。

2.在AndroidManifest.xml文件或程序代码中注册BroadcastReceiver。

3.构建intent对象。

4.调用sendBroadcast()方法发送广播。

3.实例分析

     下面通过一个小DEMO 来讲解一下广播在Android 中如何编写,在Demo中我们设置了一个按钮为按钮设置点击监听通过点击发送广播,在后台中接收到广播并打印LOG信息。

MainActivity中的代码:就是设置一个button监听事件,发送广播

public class MainActivity extends Activity {

private Button sendbroadcast;

 

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

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

sendbroadcast.setOnClickListener(new OnClickListener() {

 

public void onClick(View v) {

Intent intent = new Intent();

intent.setAction("com.example.Myreceiver.ACTION");

sendBroadcast(intent);

}

});

}

 

}

Myreceiver接收器的代码:

public class Myreceiver extends BroadcastReceiver {

private static final String TAG="Myreceiver";

@Override

public void onReceive(Context context, Intent intent) {

Log.i(TAG"Broadcast onReceiver");

Toast.makeText(context,"广播接收器", Toast.LENGTH_SHORT).show();

}

//在创建调用对象时,会实现构造方法中的方法

public Myreceiver(){

Log.i(TAG"Myreceiver");

}

 

}

效果图:点击sendbroadcast按钮,发送广播


日志打印信息:


4.Android 广播的生命周期onReceiver生命周期为10秒)

  广播的生命周期流程图如下:


如果一个广播处理完onReceive 那么系统将认定此对象将不再是一个活动的对象,也就会finished掉它。

5.Android中区分不同广播

   在Android中有很多种广播,怎么确定广播接收器接收哪一种广播呢?这是通过intent-filter过滤器来解决的接收指定action广播。

6.注册BroadcastReceiver的方法

   BroadcastReceiver用于监听被广播的事件(Intent),为了达到这个目的,BroadcastReceiver必须进行注册,注册的方法有以下两种:

1.静态注册

静态注册方式是在AndroidManifest.xml的application里面定义receiver并设置要接收的action。


静态注册方式的特点:不管改应用程序是否处于活动状态,都会进行监听。

2.动态注册

动态注册方式在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。


注册广播



注销广播

unregisterReceiver(receiver);

这里要注意的是new SecondReceiver()时,要把receiver对象声明成全局变量。private SecondReceiver receiver;这样在注册和注销时的receiver对象才是同一个对象。

动态注册方式特点:在代码中进行注册后,当应用程序关闭后,就不再进行监听。

一般在onStart中注册BroadcastReceiver,在onStop中取消BroadcastReceiver。

一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)时才有效,当从该函数返回后,该对象就无效的了,结束生命周期。


动态注册BroadcastReceiver实例:

MainActivity中的代码:

public class MainActivity extends Activity implements OnClickListener{

private Button sendbroadcast;

private Button registerbroadcast;

private Button unregisterbroadcast;

private SecondReceiver receiver;

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

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

registerbroadcast = (Button) findViewById(R.id.registerReceiver);

unregisterbroadcast = (Button) findViewById(R.id.unregisterReceiver);

registerbroadcast.setOnClickListener(this);

unregisterbroadcast.setOnClickListener(this);

sendbroadcast.setOnClickListener(new OnClickListener() {

 

public void onClick(View v) {

Intent intent = new Intent();

intent.setAction("com.example.SecondReceiver.ACTION");

sendBroadcast(intent);

}

});

}

 

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.registerReceiver:

//创建一个有参的receiver对象

receiver = new SecondReceiver(getBaseContext());

//设置过滤器和广播的类别acton

IntentFilter filter = new IntentFilter("com.example.SecondReceiver.ACTION");

//注册广播

registerReceiver(receiver, filter);

break;

case R.id.unregisterReceiver:

         unregisterReceiver(receiver);

 

default:

break;

}

 

}

 

}

SecondReceiver中的代码:

public class SecondReceiver extends BroadcastReceiver {

//当创建receiver对象时,会先调用构造方法中的方法,无参对象调用无参构造方法中的方法,这里是有参对象那么就调用有参构造方法中的方法

public SecondReceiver(Context context){

Toast.makeText(context, "创建receiver对象", Toast.LENGTH_SHORT).show();

}

 

@Override

public void onReceive(Context context, Intent intent) {

Toast.makeText(context, "动态注册广播信息", Toast.LENGTH_SHORT).show();

 

}

 

}

效果图:点击registerReceiver,创建receiver对象,调用构造方法中Toast方法。


效果图:这时注册了broadcastReceiver,点击sendbroadcast发送广播。会显示动态注册广播信息的提示信息。


效果图:点击unregisterReceiver,注销广播。


特别注意:广播的生命周期,就是内部onReceive方法的周期,当onReceiver方法结束,也就意味着广播的结束。虽然我们可以在onReceiver  内执行启动一个新线程执行耗时的业务,由于onReceiver方法周期很短暂,可能出现的情况是:子线程还没有结束广播就关闭了,广播一旦关闭,虽然子线程还可以运行,但系统会认为广播处于无组件活动的状态,在内存紧张的时候优先结束该进程,这样可能会导致子线程不能执行完任务。所以最好的方式是启动service。










 









0 0
原创粉丝点击