四大組件之BroadcastReceiver基礎

来源:http://www.cnblogs.com/joahyau/archive/2017/04/15/6714558.html
-Advertisement-
Play Games

1. 系統廣播 1.1 動態註冊   (1)創建自定義接收器類繼承自BroadcaseReceiver,實現onReceive()方法,對接收到的廣播的邏輯處理就是寫在這個函數中的。   (2)實例化IntentFilter對象,並通過addAction()方 ...


1. 系統廣播

1.1 動態註冊

  (1)創建自定義接收器類繼承自BroadcaseReceiver,實現onReceive()方法,對接收到的廣播的邏輯處理就是寫在這個函數中的。

  (2)實例化IntentFilter對象,並通過addAction()方法加入需要接收的廣播值。使用系統廣播時可查閱官方文檔,找到需要的Action。

  (3)實例化自定義接收器類的對象,並通過registerReceiver()方法註冊接收器對象。

  (4)在AndroidManifest.xml文件中,通過uses=permission標簽進行許可權聲明。若非系統的關鍵性信息,則無需這一步。

  (5)使用完後,動態註冊的廣播接收器一定要通過unregisterReceiver()方法取消註冊。

範例: 監測當前網路狀態,若斷網,則提示用戶當前網路不可用。

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.studying.myapplication">

    <!--聲明許可權-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".BroadcaseActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

活動類:

public class BroadcaseActivity extends Activity {

    private IntentFilter mFilter;
    private NetworkChangeReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcase);

        //實例化IntentFilter對象,並加入Action
        mFilter = new IntentFilter();
        mFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        mReceiver = new NetworkChangeReceiver();
        //註冊接收器
        registerReceiver(mReceiver, mFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //動態註冊的廣播接收器一定要取消註冊
        unregisterReceiver(mReceiver);
    }

    class NetworkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //獲取網路狀態信息
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

            //當網路信息對象為空或者網路不可用時,提示用戶
            if (networkInfo == null || !networkInfo.isAvailable()) {
                Toast.makeText(context, "Network is unavailable.", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

1.2 靜態註冊

  相對動態註冊而言,靜態註冊接收器非常簡單,只需要自定義一個接收器類,而後實現onReceive()方法,在裡面實現對廣播的處理,然後在AndroidManifest.xml文件中通過receiver標簽進行註冊即可。需要註意,無論是靜態註冊還是動態註冊,如果需要訪問系統的關鍵性信息,都必須在配置文件中聲明許可權。

範例: 靜態註冊實現開機自啟。

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.studying.myapplication">

    <!--聲明許可權-->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--通過receiver標簽靜態註冊-->
        <receiver android:name=".BootCompleteReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <activity android:name=".BroadcaseActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

自定義接收器類:

public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Boot Complete..", Toast.LENGTH_SHORT).show();
    }
}

2. 自定義廣播

2.1 標準廣播

  自定義廣播的接收方法與系統廣播的一樣,也有靜態註冊和動態註冊兩種方法,這裡就不再贅述。

  自定義廣播的不同之處在於,它是手動發送的,方法是新建一個Intent對象並加入自定義的廣播值,而後通過sendBroadcase()方法發送,此時發送出去的就是一條標準廣播。

範例: 發送一條自定義標準廣播並接收。

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.studying.myapplication">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--通過receiver標簽靜態註冊-->
        <receiver android:name=".MyReceiver" >
            <intent-filter>
                <action android:name="com.studying.MyBroadcast" />
            </intent-filter>
        </receiver>

        <activity android:name=".BroadcaseActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

自定義接收器類:

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Received.", Toast.LENGTH_SHORT).show();
    }
}

佈局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context="com.studying.myapplication.BroadcaseActivity">

    <Button
        android:id="@+id/send"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="Send MyBroadcase" />
</LinearLayout>

活動類:

public class BroadcaseActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcase);

        Button send = (Button) findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //實例化一個Intent對象,併發送廣播
                Intent intent = new Intent("com.studying.MyBroadcast");
                sendBroadcast(intent);
            }
        });
    }
}

2.2 有序廣播

  與標準廣播不同之處在於,標準廣播是非同步執行的,所有廣播接收器會在同一時刻接收到;而有序廣播是同步執行的,同一時刻只會有一個接收器收到,當這個接收器裡面的邏輯執行完畢後,廣播才會繼續傳播。

  因此,有序廣播有兩個要點,第一,優先順序高的接收器可以先收到廣播,優先順序高低通過priority給定;第二,前面的接收器可以截斷,讓後面的接收器無法收到廣播,這個則是通過abortBroadcase()方法實現。

  此外,有序廣播是通過sendOrderedBroadcase()方法進行發送的。

範例: 創建兩個自定義廣播類,並且讓MyReceiver1的優先順序高於MyReceiver2,而後在MyReceiver1中調用abortBroadcase()方法截斷廣播的傳遞。

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.studying.myapplication">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--使MyReceiver1的優先順序高於MyReceiver2的-->
        <receiver android:name=".MyReceiver1" >
            <intent-filter android:priority="100">
                <action android:name="com.studying.MyBroadcast" />
            </intent-filter>
        </receiver>
        <receiver android:name=".MyReceiver2" >
            <intent-filter android:priority="50">
                <action android:name="com.studying.MyBroadcast" />
            </intent-filter>
        </receiver>

        <activity android:name=".BroadcaseActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

佈局文件與標準廣播的範例一樣:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context="com.studying.myapplication.BroadcaseActivity">

    <Button
        android:id="@+id/send"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="Send MyBroadcase" />
</LinearLayout>

活動類:

public class BroadcaseActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcase);

        Button send = (Button) findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //發送有序廣播
                Intent intent = new Intent("com.studying.MyBroadcast");
                sendOrderedBroadcast(intent, null);
            }
        });
    }
}

MyReceiver1:

public class MyReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Received in MyReceiver1.", Toast.LENGTH_SHORT).show();
        abortBroadcast();
    }
}

MyReceiver2:

public class MyReceiver2 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Received in MyReceiver2.", Toast.LENGTH_SHORT).show();
    }
}

  若把MyReceiver1中的abortBroadcase();這一句註釋掉,點擊發送則可一次看到兩個接收器的提示。

3. 本地廣播

  本地廣播只能夠在應用程式內部進行傳遞,廣播接收器也只能接收本程式發出的廣播,這樣的機制解決了全局廣播可能出現的安全問題。

  使用本地廣播非常簡單,與全局廣播不一樣的地方在於,使用了一個LocalBroadcastManager對廣播進行管理,使用這個管理器發送的廣播以及註冊的接收器,即為本地廣播和本地廣播接收器。

  另外,由於發送本地廣播時,程式必定處於啟動狀態,因而不需要並且也沒有靜態註冊。

範例: 發送一條本地廣播並接收。

活動類:

public class BroadcaseActivity extends Activity {

    private MyReceiver mReceiver;
    private LocalBroadcastManager mManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcase);

        //獲取本地廣播管理器
        mManager = LocalBroadcastManager.getInstance(this);

        Button send = (Button) findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //通過本地廣播管理器發送廣播
                Intent intent = new Intent("com.studying.MyLocalBroadcast");
                mManager.sendBroadcast(intent);
            }
        });

        //通過本地廣播管理器進行動態註冊
        IntentFilter mFilter = new IntentFilter();
        mFilter.addAction("com.studying.MyLocalBroadcast");
        mReceiver = new MyReceiver();
        mManager.registerReceiver(mReceiver, mFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //通過本地廣播管理器取消註冊
        mManager.unregisterReceiver(mReceiver);
    }

    //自定義接收器類
    class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "Received.", Toast.LENGTH_SHORT).show();
        }
    }
}

  最後,在使用廣播接收器時要註意,不要在onReceive()方法中加任何耗時操作,廣播接收器更多的是接收某些廣播訊息,從而開啟其它組件。在廣播接收器中是不允許開啟線程的,當onReceive()方法運行了長時間仍未結束時,程式就會報錯。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在使用一些產品列如微信、QQ之類的,如果有新消息來時,手機屏幕即使在鎖屏狀態下也會亮起並提示聲音,這時用戶就知道有新消息來臨了。但是,一般情況下手機鎖屏後,Android系統為了省電以及減少CPU消耗,在一段時間後會使系統進入休眠狀態,這時,Android系統中CPU會保持在一個相對較低的功耗狀態。 ...
  • 第一步: 為mac電腦配置 adb 命令的環境變數,分為2小步 1.找到 Android Studio 為你安裝的 SDK : 打開電腦中 Android studio 的工具的軟體,在啟動 Android studio 的軟體的界面中,點擊下方列表中的”configure“的選項。在點擊列表中的“ ...
  • 轉載請註明出處:http://www.cnblogs.com/cnwutianhao/p/6719380.html 作為Android開發者,一定不會對 GreenDao 和 ReactiveX 陌生。 GreenDao 號稱Android最快的關係型資料庫 ReactiveX Rx是一個編程模型, ...
  • 在使用pthread進行NDK中的多線程開發時,自己寫了一個BUG, 這個是啟動函數,即相當於Java中的Thread的run方法。初一看沒啥問題,編譯也能過,APP也能跑,但是每次都會crash。我把crash線程的log貼出來如下: 從log中看出,是記憶體訪問錯誤,然後使用addr2line工具 ...
  • 作者:Antonio Leiva 時間:Apr 11, 2017 原文鏈接:https://antonioleiva.com/dagger-android-kotlin/ 在Android上,創建去耦以及容易測試代碼的幾乎每位遲早都要訴諸Dagger。 雖然,在Kotlin中設置Dagger有一些不 ...
  • 在Android應用crash的類型中,native類型crash應該是比較難的一種了,因為大家接觸的少,然後相對也要多轉幾道工序,所有大部分對這個都比較生疏。雖然相關文章也有很多了,但是我在剛開始學的過程中還是遇到一些問題,下麵一一記錄,以便將來翻閱。 分析native crash 日誌需要幾個東 ...
  • 在繼承ViewGroup類時,需要重寫兩個方法,分別是onMeasure和onLayout。 1,在方法onMeasure中調用setMeasuredDimension方法void android.view.View.setMeasuredDimension(int measuredWidth, i ...
  • 下麵以使用軟引用為例來詳細說明。弱引用的使用方式與軟引用是類似的。 假設我們的應用會用到大量的預設圖片,比如應用中有預設的頭像,預設游戲圖標等等,這些圖片很多地方會用到。如果每次都去讀取圖片,由於讀取文件需要硬體操作,速度較慢,會導致性能較低。所以我們考慮將圖片緩存起來,需要的時候直接從記憶體中讀取。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...