BroadcastReceiver

轉載請標明出處: 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>

這裏寫圖片描述

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