学习BroadcastReceiver

本次内容参考于《疯狂的android》第3版的个人学习笔记
————————————————————————————————

  Android系统的四大组件还有一种就是BroadcastReceiver,这种组件本质上就是全局监听器,用于接收程序(用户开发的程序和系统内建的程序)所发出的Broadcast Intent。

Broadcast被分为如下两种:

  • 正常广播 Normal broadcasts(用 Context.sendBroadcast()发送):是完全异步的,可以在同一时刻被所有接受者接收到,消息传递的效率比较高,但缺点是接收者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的传播。
  • 序广播 Ordered broadcasts(用 Context.sendOrderedBroadcast()发送):所谓有序,就是每个receiver执行后可以传播到下一个receiver,也可以完全中止传播,在代码中写入abortBroadcast();即可。优先级别声明在<intent-filter.../>元素的android:priority属性中,数越大优先级别越高,取值范围为-1000~1000。优先接到Broadcast的接收者可以通过setResultExtra(Bunble)方法将处理结果存入Broadcast中,然后传给下一次接收者。下一个接收者通过代码Bundle bundle = getResuleExtras(true)获取上一级接收者存入的数据。(String data = bundle.getString("data");)

通过sendBroadcast()来发送广播:

1.新建BroadcastReceiver文件MyReceiver:

MainActivity的代码:

public class MainActivity extends ActionBarActivity implements View.OnClickListener {

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

        findViewById(R.id.btgb).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btgb:
                Intent intent = new Intent();
                intent.setAction("songsong.com.broadcastreceivertext.intent.action.MyReceiver");
               sendBroadcast(intent);
                break;
        }
    }
}

MyReceiver.java文件内容:

public class MyReceiver extends BroadcastReceiver {
    public MyReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("MyReceiver");
    }
}
当符合该MyReceiver的广播出现时,onReceive方法将会被触发,从而在该方法中显示消息。

在AndroidManifest中application定义

  <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true" >
  <intent-filter>
          <action android:name:"songsong.com.broadcastreceivertext.intent.action.MyReceiver"/>
  </intent-filter>
</receiver>

上面发送广播的程序中指定发送广播时所用的Intent的Action为songsong.com.broadcastreceivertext.intent.action.MyReceiver

-----------------------------------------------------


通过sendOrderedBroadcast()来发送广播:

接下来是一个发送有序广播的示例,Activity界面上只有一个按钮,用于发送一条有序广播:

MyReceiver.java文件内容:

public class MainActivity extends ActionBarActivity {

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

          findViewById(R.id.btnsend).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                   
               Intent intent = new Intent();//创建Intent对象
                intent.setAction("songsong.com.broadcast_orderd.intent.action.MyReceiver");
                intent.putExtra("msg", "简单的第1条信息");
                sendOrderedBroadcast(intent, null);    //发送有序广播,null为权限
            }
        });
    }
程序中指定了Intent的Action属性,再调用sendOrderedBroadcast()方法来发送有序广播,它会按优先级依次触发每个BroadcastReceiver的OnReceive()方法。

接下来定义第一个BroadcastReceiver

public class MyReceiver extends BroadcastReceiver {
    public MyReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, intent.getAction() + intent.getStringExtra("msg"), Toast.LENGTH_SHORT).show();

        Bundle bundle = new Bundle();//创建一个Bundle对象并存入信息 

        bundle.putString("data1", "这是第一个MyReceiver发出的信息");

        setResultExtras(bundle);   //将Bundle放入结果中

        //abortBroadcast();//取消Broadcast继续传播
    }
}
上面BroadcastReceiver不仅处理了所接收到的消息,而且还处理结果中存入的key为“data1”的消息,这个消息将可以被第二个BroadcastReceiver解析出来。

如果abortBroadcast();代码执行,Broadcast将会终止传播,那么优先级别比MyReceiver  低的BroadcastReceiver将不会被触发

在AndroidManifest.xml文件中部署该BroadcastReceiver,并指定优先级为20,如下:

    <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true" >
            <intent-filter android:priority="20" >
                <action android:name="songsong.com.broadcast_orderd.intent.action.MyReceiver" />
            </intent-filter>
        </receiver>
接下来为程序提供第二个 BroadcastReceiver,这个将会解析前一个 BroadcastReceiver所存入的key为data1的消息。如下:

public class MyReceiver2 extends BroadcastReceiver {
    public MyReceiver2() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = getResultExtras(true);

       String data = bundle.getString("data1");//解析前一个<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">BroadcastReceiver</span></span></span>所存入的key为data1的消息

       Toast.makeText(context, data, Toast.LENGTH_SHORT).show();

    }
}
在AndroidManifast.xml文件中配置该 BroadcastReceiver,并指定优先级别为19,如下:

 <receiver
            android:name=".MyReceiver2"
            android:enabled="true"
            android:exported="true" >
            <intent-filter android:priority="19" >
                <action android:name="songsong.com.broadcast_orderd.intent.action.MyReceiver" />
            </intent-filter>
        </receiver>
MyReceiver的优先级更高点,MyReceiver2略低, abortBroadcast();被注释的情况下,那么程序会先运行MyReceiver再到MyReceiver2。如果abortBroadcast();没有被注释的话,程序只运行MyReceiver。

——————————————————————————

BroadcastReceiver指定Intent,有两种方式:

1、使用代码进行指定,调用BroadcastReceiver的context的registerReceiver(BroadcastReceiver receiver,filter)方法指定,代码如下:

        ActivityReceiver activityReceiver = new ActivityReceiver();
      
       IntentFilter filter = new IntentFilter();

       filter.addAction("songsong.com.broadcast_orderd.intent.action.MyReceiver");
      
       registerReceiver(activityReceiver, filter); //注册广播

2、在AndroidManifest.xml文件中配置。如下:

        <receiver
            android:name=".MyReceiver">
            <intent-filter>
                <action android:name="songsong.com.broadcast_orderd.intent.action.MyReceiver" />
            </intent-filter>
        </receiver>

--------------------------------------------------

在BroadCast 中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity 或者 Service 去处理。





你可能感兴趣的:(android,四大组件)