轉載請標明出處: http://blog.csdn.net/wu_wxc/article/details/51394220
本文出自【吳孝城的CSDN博客】
關於廣播的內容,可以看下官方的介紹:http://developer.android.com/intl/zh-cn/reference/android/content/BroadcastReceiver.html
廣播的生命週期只在調用onReceive(Context, Intent)時活躍。
廣播分兩種
Normal broadcasts:標準廣播,無序廣播
通過Context.sendBroadcast發送,是完全異步的,所有的接收器以不確定的順序運行,通常是同時的,這樣效率更高,但也意味着接收器不能傳遞結果,也不能中止廣播。
Ordered broadcasts:有序廣播
通過Context.sendOrderedBroadcast發送,一次只發送給一個接收器,每個接收器按順序執行,所以它可以向下一個接收器傳遞結果,也可以退出廣播,不再傳遞給其他接收器,接收器的運行順序可以通過android:priority屬性控制,如< intent-filter android:priority = “1000” >,級別數值在-1000到1000之間,值越大,優先級越高。相同優先級的接收器會以隨機的順序執行。
註冊
我們可以用Context.registerReceiver()在程序中動態註冊廣播,動態註冊的需程序啓動後才能接收廣播。
也可以通過在AndroidManifest.xml中靜態註冊,靜態註冊的可以讓程序在未啓動的情況下接收廣播。
如果在Activity.onResume()裏註冊了一個receiver,就應該在Activity.onPause()裏調用unregisterReceiver()註銷它,暫停後將不會收到intents,這將減少不必要的系統開銷,不用在Activity.onSaveInstanceState()註銷,因爲用戶回到歷史堆棧它將不會被調用。
注意
不要在廣播裏添加任何邏輯和耗時操作,因爲廣播不允許開闢線程,當onReceive(Context, Intent)運行時間超過10秒還沒有結束時,程序會報錯(ANR),廣播更多的是用來打開其他組件,如Service,Activity,Notification提示等。
接收廣播
接下來來實踐一下
創建一個類,繼承BroadcastReceiver
在onReceive(Context context, Intent intent)方法裏完成廣播要做的事。
動態註冊
MyReceiver.java
package cn.wuxiaocheng.broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
// 在onReceive裏完成廣播要操作的事,這裏彈出一個吐絲
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "網絡狀態發生改變~", Toast.LENGTH_SHORT).show();
}
}
在MainActivity.java中動態註冊
package cn.wuxiaocheng.broadcastreceiver;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
MyReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new MyReceiver();
// 創建意圖過慮器
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
// 註冊Receiver
registerReceiver(myReceiver, filter);
}
// 註銷廣播
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(myReceiver);
}
}
在AndroidManifest.xml裏聲明
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true"></receiver>
靜態註冊
MyReceiver.java
package cn.wuxiaocheng.broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
private final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";
public MyReceiver() {
}
// 在onReceive裏完成廣播要操作的事,這裏彈出一個吐絲
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_BOOT.equals(intent.getAction()))
Toast.makeText(context, "已開機", Toast.LENGTH_LONG).show();
}
}
在AndroidManifest.xml裏聲明和添加intent-filter
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.cation.BOOT_COMPLETED" />
</intent-filter>
</receiver>
發送廣播
這裏只寫一個標準廣播擴運行,有序廣播的可以自己寫一下。或者我有空再來補充
標準廣播用:sendBroadcast
有序廣播用:sendOrderedBroadcast
先寫一個程序,創建一個繼承BroadcastReceiver的類,實現onReceive(Context context, Intent intent)方法
MyReceiver.java
package cn.wuxiaocheng.broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
private final String GET_Broadcast = "cn.wuxiaocheng.MY_BROADCAST";
public MyReceiver() {
}
// 在onReceive裏完成廣播要操作的事,這裏彈出一個吐絲
@Override
public void onReceive(Context context, Intent intent) {
if (GET_Broadcast.equals(intent.getAction()))
// 當收到其他應用程序發送的廣播時,會彈出Toast
Toast.makeText(context, "收到廣播", Toast.LENGTH_LONG).show();
}
}
在AndroidManifest.xml裏聲明和添加intent-filter
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="cn.wuxiaocheng.MY_BROADCAST"/>
</intent-filter>
</receiver>
再寫一個程序,用來發送廣播
只需要寫一行發送代碼就行
sendBroadcast(new Intent("cn.wuxiaocheng.MY_BROADCAST"));
寫一個按鈕,點擊發送廣播
package cn.wuxiaocheng.testbroadcast;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void send(View v){
sendBroadcast(new Intent("cn.wuxiaocheng.MY_BROADCAST"));
}
}
發送後接收廣播的程序應付彈出Toast
LocalBroadcastManager
如果我們不需要跨程序發送廣播,可以選用:LocalBroadcastManager
注意:
1.本地廣播無法通過靜態註冊方式來接收,相比起全局廣播要高效很多
2.在廣播中啓動Activity時,需要爲intent添加FLAG_ACTIVITY_NEW_TASK,不然會報錯,因爲需要一個棧來存放新打開的Activity
3.在廣播中彈出AlertDialog時需要在AndroidManifest.xml設置對話框的類型爲TYPE_SYSTEM_ALERT,不然無法彈出< uses-permission android:name=”android.permission.SYSTEM_ALERT_WINDOW” />
來個小例子
MainActivity.java
package cn.wuxiaocheng.testbroadcast;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private LocalBroadcastManager mLcalBroadcastManager;
private BroadcastReceiver mBroadcastReceiver;
private IntentFilter mIntentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLcalBroadcastManager = LocalBroadcastManager.getInstance(this);
// 初始化廣播接收者
mBroadcastReceiver = new MyReceiver();
// 創建意圖過慮器
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("cn.wuxiaocheng.LOCAL_BROADCAST");
// 註冊Receiver
mLcalBroadcastManager.registerReceiver(mBroadcastReceiver, mIntentFilter);
}
public void send(View v) {
Intent intent = new Intent("cn.wuxiaocheng.LOCAL_BROADCAST");
mLcalBroadcastManager.sendBroadcast(intent);
}
// 註銷廣播
@Override
protected void onPause() {
super.onPause();
mLcalBroadcastManager.unregisterReceiver(mBroadcastReceiver);
}
}
MyReceiver.java
package cn.wuxiaocheng.testbroadcast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
private final String GET_Broadcast = "cn.wuxiaocheng.LOCAL_BROADCAST";
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
if (GET_Broadcast.equals(intent.getAction()))
// 當收到其他應用程序發送的廣播時,會彈出Toast
Toast.makeText(context, "LocalBroadcastManager", Toast.LENGTH_LONG).show();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="cn.wuxiaocheng.testbroadcast.MainActivity">
<Button
android:onClick="send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="發送廣播" />
</RelativeLayout>