18、從頭學Android之BroadcastReceiver

BroadcastReceiver簡介

BroadcastReceiver理解爲廣播接收者,它用於接收程序所發出的Broadcast的Intent。它在一端監聽接收廣播消息,然後再做出處理。它的本質上就是屬於一個監聽器。啓動BroadcastRecevicer的方式有兩種:sendBroadcast()和sendOrderedBroadcast(),兩者的區別就是前者是發送一個普通的廣播,後者是發送一個有序的廣播。

開發廣播接收才的步驟:

1、  繼承BroadcastReceiver類,重寫onReceiver(Context context,Intent intent)方法

2、  在AndroidMainfest.xml中註冊,同樣也可以在代碼中實現註冊

3、  通過sendBroadcast()或sendOrderedBroadcast()啓動對應的BroadcastReceiver

下面分別介紹:

實現廣播消息處理機制的方式

繼承BroadcastReceiver,覆蓋onReceive

public class MyReceiver extends BroadcastReceiver {
     public MyReceiver() {
      System.out.println("--myReceiver constructor--");
    }
    public void onReceive(Context context, Intent intent) {
       System.out.println("--onReceive--");
       //取到信息
       String receiveMsg = intent.getStringExtra("msg");
       Toast.makeText(context, receiveMsg, Toast.LENGTH_LONG).show();
    }

}

註冊BroadcastReceiver的兩種方式:

方式一:AndroidMainfest.xml中註冊:

<receiver android:name=".MyReceiver">
           <intent-filter>
              <action android:name="com.jiahui.activity.MY_ACTION" />
           </intent-filter>
       </receiver>

方式二:應用程序代碼中註冊

 

myReceiver2 = new MyReceiver2();
              IntentFilter intentFilter = new IntentFilter();
              Intent intent=new Intent(); 
              intentFilter.addAction(SMS_ACTION);
              registerReceiver(myReceiver2, intentFilter);


 


兩種註冊方式的區別:

1)第一種是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。

2)第二種不是常駐型廣播,也就是說廣播跟隨程序的生命週期。

 

廣播的類型:

廣播被分爲兩種不同的類型:“普通廣播(Normal broadcasts)”和“有序廣播(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,然後傳給下一個接收者。

 

再總結說說兩種廣播的區別比較:

普通廣播:異步,數據不共享,傳遞效率高

有序廣播:同步,數據可以達到共享,傳遞效率低

說了這麼一大堆,是不是都暈,那就上實例吧

實例1:發送普通廣播

1、 寫一個繼承於BroadcastReceiver的類,並重寫onReceiver方法

package com.jiahui.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyBroadcastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		Toast.makeText(
				context,
				"接收到的Intent的Action爲" + intent.getAction() + "\n傳遞的消息內容爲"
						+ intent.getStringExtra("msg"), Toast.LENGTH_LONG)
				.show();

	}

}


2、 在AndroidMainfest.xml中註冊

      <receiver android:name=".MyBroadcastReceiver" >
            <intent-filter >
                <action android:name="com.jiahui.broadcast.mybroadcast" />
            </intent-filter>
        </receiver>


3、 在Activity中發送廣播

package com.jiahui.broadcast;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class BroadcastDemo1Activity extends Activity {

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		Button btnSend = (Button) this.findViewById(R.id.btnSend);

		btnSend.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {

				Intent intent = new Intent();
				// 指定發送特定的BroadcastReceiver
				intent.setAction("com.jiahui.broadcast.mybroadcast");

				// 帶一些消息內容過去
				intent.putExtra("msg", "我發過來的數據哦");

				sendBroadcast(intent);

			}
		});

	}
}


實現效果:

 

實例2:發送有序廣播

寫兩個BroadcastReceiver類

MyReceiver01.java:

package com.jiahui.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

public class MyReceiver1 extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {

		System.out.println("---MyReceiver1----onReceive---");
		String receiverMsg = intent.getStringExtra("msg");
		System.out.println("receiverMsg:" + receiverMsg);
		Toast.makeText(

				context,
				"接收到的Intnet的action" + intent.getAction() + "\n發過來的消息內容:"
						+ receiverMsg, 5000).show();

		Bundle bundle = new Bundle();
		bundle.putString("first", "第一個廣播接收者給的數據");
		// 放入下一個結果中,讓下一個廣播接收者收到消息
		setResultExtras(bundle);

	}
}


 MyReceiver02.java

package com.jiahui.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

public class MyReceiver2 extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		System.out.println("---MyReceiver2----onReceive---");
		// 取到結果
		Bundle bundle = getResultExtras(true);

		String receiverMsg = bundle.getString("first");

		System.out.println("receiverMsg:" + receiverMsg);

		Toast.makeText(

				context,
				"接收到的Intnet的action" + intent.getAction() + "\n發過來的消息內容:"
						+ receiverMsg, 5000).show();

	}

}

在Androidmainfest.xml中文件註冊,同時設置爲優先級

 <receiver android:name=".MyReceiver1" >
            <intent-filter android:priority="20" >
                <!-- 設置廣播接收者的優先級 -->
                <action android:name="com.jiahui.broadcast.myreceiver" />
            </intent-filter>
        </receiver>
        <receiver android:name=".MyReceiver2" >
            <intent-filter android:priority="10" >
                <!-- 設置廣播接收者的優先級 -->
                <action android:name="com.jiahui.broadcast.myreceiver" />
            </intent-filter>
        </receiver>


注意:這裏兩個廣播接收者設置的action是一樣

開發Activity在Activity中發送有序廣播消息

package com.jiahui.broadcast;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class BroadcastDemo2Activity extends Activity {

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		Button btnSend = (Button) this.findViewById(R.id.btnSend);

		btnSend.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				Intent intent = new Intent();
				intent.setAction("com.jiahui.broadcast.myreceiver");

				intent.putExtra("msg", "發給第一個接收者的數據");
				// 發送有序廣播
				sendOrderedBroadcast(intent, null);
			}
		});
	}
}


 

實現效果:

當一段時間我們就可以看到又會彈出一個信息如下圖:

也可以通過控制檯監視:

開發BroadcastReceiver的一些注意事項:

BroadcastReceiver的生命週期比較短,一些比較費時的操作不應該放在onReceiver裏完成。如果在onReceiver()的方法不能在10秒內執行完成,將會產生程序無響應也就是我們熟悉的ANR(Application not Response)。但是如果非得要在這裏面執行一些費時的操作我們可以在這個onReceiver去啓動一個Service來完成這樣的一個費時操作。

 

如需轉載引用請註明出處:http://blog.csdn.net/jiahui524

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章