1 Broadcast是Android中的四大组件之一,他的用途很大,比如系统的一些广播:电量低、开机、锁屏等一些操作都会发送一个广播。
2 广播被分为两种不同的类型:“普通广播(Normalbroadcasts)”和“有序广播(Ordered broadcasts)”.普通广播是完全异步的,可以在同一时刻(逻辑上)被所有广播接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;然后有序广播是按照接收者声明的优先级别(声明在intent-filter元素的android:priority)属性中,数越大优先级别越高,取值范围:-1000到1000。也可以调用IntentFilter对象的setPriority()进行设置),被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传A,在传给B,最后传给C,A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
Context.sendBroadcast()
发送的是普通广播,所有订阅者都有机会获得并进行处理。
Context.sendOrderedBroadcast()
发送的是有序广播,系统会根据接收者声明的优先级按顺序逐个执行接收者,前面的接收者有权终止广播(通过调用BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将处理结果存进广播Intent,然后传给下一个接收者。
编写以下案例:
3 编写Android清单文件
xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima.broadcasttest" android:versionCode="1" android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima.broadcasttest.MainActivity" android:label="@string/app_name" > <intent-filter> <actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" /> intent-filter> activity>
<receiverandroid:name="com.itheima.broadcasttest.Level1Receiver" > <intent-filter android:priority="1000" > <actionandroid:name="com.itheima.broadcasttest.songwennuan" /> intent-filter> receiver> <receiverandroid:name="com.itheima.broadcasttest.Level2Receiver" > <intent-filter android:priority="500" > <actionandroid:name="com.itheima.broadcasttest.songwennuan" /> intent-filter> receiver> <receiverandroid:name="com.itheima.broadcasttest.Level3Receiver" > <intent-filter android:priority="100" > <actionandroid:name="com.itheima.broadcasttest.songwennuan" /> intent-filter> receiver> <receiver android:name="com.itheima.broadcasttest.FinalReceiver"> <intent-filter android:priority="0" > <actionandroid:name="com.itheima.broadcasttest.songwennuan" /> intent-filter> receiver> application>
manifest> |
4 编写布局文件activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" >
<Button android:onClick="send1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="发送无序广播" />
<Button android:onClick="send2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="发送有序广播" />
LinearLayout> |
5 编写一下广播接收者
Level1Receiver
package com.itheima.broadcasttest;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log;
public class Level1Receiver extends BroadcastReceiver { private static final String TAG = "Broadcasttest";
@Override public void onReceive(Context context, Intent intent) { String message = getResultData(); Log.i(TAG,"省级部门得到中央的消息:" + message); abortBroadcast(); //这里是终止了消息,可以关闭或者取消这里查看LogCat中打印的效果。 setResultData("给农民兄弟发5000块钱"); }
} |
Level2Receiver
package com.itheima.broadcasttest;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log;
public class Level2Receiver extends BroadcastReceiver { private static final String TAG = "Broadcasttest";
@Override public void onReceive(Context context, Intent intent) { String message = getResultData(); Log.i(TAG,"市级部门得到省级的消息" + message); setResultData("给农民兄弟发2000块钱"); }
} |
Level3Receiver
package com.itheima.broadcasttest;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log;
public class Level3Receiver extends BroadcastReceiver { private static final String TAG = "Broadcasttest";
@Override public void onReceive(Context context, Intent intent) { String message = getResultData(); Log.i(TAG, "乡级部门得到市的消息:" + message); setResultData("给农民兄弟发两大大米"); }
} |
FinalReceiver
package com.itheima.broadcasttest;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log;
public class FinalReceiver extends BroadcastReceiver { private static final String TAG = "Broadcasttest";
@Override public void onReceive(Context context, Intent intent) { String message = getResultData(); Log.i(TAG, "农民兄弟得到乡的消息:" + message); } } |
6 MainActivity的内容如下:
package com.itheima.broadcasttest;
import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.View;
public class MainActivity extends ActionBarActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
/** * 发送无序广播 * @param view */ public void send1(View view) { Intent intent = new Intent(); intent.setAction("com.itheima.broadcasttest.songwennuan"); intent.putExtra("msg", "发1万块"); //无序广播,不可被拦截,不可终止 sendBroadcast(intent); }
public void send2(View view) { Intent intent = new Intent(); intent.setAction("com.itheima.broadcasttest.songwennuan"); //有序广播,可被拦截,可终止,可以修改数据 sendOrderedBroadcast(intent, null,new FinalReceiver(),null,0,"给农民兄弟发10000块钱",null); } } |
运行:
点击”发送无序广播”按钮,在LogCat中打印出的内容如下:
点击” 发送有序广播”按钮,在LogCat中打印出的内容如下:
之所以在Level1Receiver执行了abortBroadcast()后还显示下面一条,是因为指定了之中广播:
//有序广播,可被拦截,可终止,可以修改数据 sendOrderedBroadcast(intent, null,new FinalReceiver(),null,0,"给农民兄弟发10000块钱",null); |
若把Level1Receiver改成如下时:
package com.itheima.broadcasttest;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log;
public class Level1Receiver extends BroadcastReceiver { private static final String TAG = "Broadcasttest";
@Override public void onReceive(Context context, Intent intent) { String message = getResultData(); Log.i(TAG,"省级部门得到中央的消息:" + message); //abortBroadcast(); //这里是终止了消息,可以关闭或者取消这里查看LogCat中打印的效果。 setResultData("给农民兄弟发5000块钱"); } } |
点击”发送有序广播”后显示的内容如下:
==========================================================================
关于有序广播的另外的一个案例:
1、编写第一个广播MyOrderBroadcastReciver
package com.demoorderbroadcast;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log;
public class MyOrderBroadcastReciver extends BroadcastReceiver {
private static final String TAG = "BroadCast";
@Override public void onReceive(Context context, Intent intent) { String strMsg = intent.getStringExtra("msg"); Log.i(TAG, "第一个:" + strMsg); //通过Bundle传递参数 Bundle extras = new Bundle(); extras.putString("msg", "第一个界面传过来的" + strMsg); setResultExtras(extras);//继续向下传 } } |
2 编写第二个广播MyOrderBroadcastReciverTwo
package com.demoorderbroadcast;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log;
public class MyOrderBroadcastReciverTwo extends BroadcastReceiver {
private static final String TAG = "BroadCast";
@Override public void onReceive(Context context, Intent intent) { //abortBroadcast(); //开启此处,可以截断广播,不让它传到third中 String strMsg = intent.getStringExtra("msg"); //获取广播的原始数据
Log.i(TAG, "第二个界面传过来的" + strMsg); Bundle extras = new Bundle(); extras.putString("msg", "第二个界面传过来的" + strMsg); setResultExtras(extras); //继续向下传
//"第二个:"+strMsg这是two中新的数据,传递到third中, //在third中是用getResultData来获得setResultData("")中的数据 setResultData("第二个:" + strMsg); }
} |
3 编写第三个广播MyOrderBroadcastReciverThird
package com.demoorderbroadcast;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log;
public class MyOrderBroadcastReciverThird extends BroadcastReceiver { private static final String TAG = "BroadCast";
@Override public void onReceive(Context context, Intent intent) { //获得two中setResultData中的数据 String resultData = getResultData(); //获取two中setResultExtras中的数据 Bundle bundle = getResultExtras(true); //获取广播的原始数据 String bundleData = bundle.getString("msg");
//获取广播的原始数据 String strMsg = intent.getStringExtra("msg"); Log.i(TAG, "第三个:" + strMsg);
Log.i(TAG,"two中传递到third新的数据:" + resultData); Log.i(TAG, "two中setResultExtras(extras)传到third新的数据:" + bundleData); } } |
4 编写MainActivity,代码如下:
package com.demoorderbroadcast;
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;
public class MainActivity extends Activity {
private Button btnSendOrderBroadCast;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); }
private void initView() { btnSendOrderBroadCast = (Button) this.findViewById(R.id.btn); btnSendOrderBroadCast.setOnClickListener(new MyOnclickListener()); }
private class MyOnclickListener implements OnClickListener {
public void onClick(View v) { if (btnSendOrderBroadCast==v) { sendOrderBroadCast(); } } }
public void sendOrderBroadCast() { Intent intent = new Intent("com.pzf.mybroadcast"); intent.putExtra("msg", "toto ni hao"); sendOrderedBroadcast(intent, "com.pzf.permission"); } } |
5 编写Android的清单文件AndroidManifest.xml
xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.demoorderbroadcast" android:versionCode="1" android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <permission android:name="com.pzf.permission"android:protectionLevel="normal"> <uses-permission android:name="com.pzf.permission"/>
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.demoorderbroadcast.MainActivity" android:label="@string/app_name" > <intent-filter> <actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" /> intent-filter> activity> <receiverandroid:name="com.demoorderbroadcast.MyOrderBroadcastReciver"> <intent-filter android:priority="1000"> <action android:name="com.pzf.mybroadcast"> intent-filter> receiver> <receiverandroid:name="com.demoorderbroadcast.MyOrderBroadcastReciverTwo"> <intent-filter android:priority="900"> <action android:name="com.pzf.mybroadcast"> intent-filter> receiver> <receiverandroid:name="com.demoorderbroadcast.MyOrderBroadcastReciverThird"> <intent-filter android:priority="800"> <action android:name="com.pzf.mybroadcast"> intent-filter> receiver> application> manifest> |
当点击“发送有序广播”时,LogCat中打印的内容如下: