學習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 去處理。





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