欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 零基礎(chǔ)到精通之廣播機制

 更新時間:2021年10月12日 10:32:28   作者:低吟不作語  
Android 提供了一套完整的 API,允許應(yīng)用程序自由地發(fā)送和接收廣播。發(fā)送廣播需要借助之前學(xué)習(xí)的 Intent,而接收廣播的方法則需要引入一個新的概念 —— BroadcasterReceiver

廣播機制簡介

Android 中的廣播主要分為兩種類型:

  • 標(biāo)準(zhǔn)廣播:一種異步執(zhí)行的廣播,廣播發(fā)出后,所有的 BroadcasterReceiver 幾乎會在同一時刻受到這條廣播消息,沒有任何時間順序
  • 有序廣播:一種同步執(zhí)行的廣播,廣播發(fā)出后,同一時刻只有一個 BroadcasterReceiver 能夠接受這條廣播消息,當(dāng)該 BroadcasterReceiver 中的邏輯執(zhí)行完畢后,廣播才會繼續(xù)傳遞

接收系統(tǒng)廣播

Android 內(nèi)置了很多系統(tǒng)級別的廣播,我們可以在應(yīng)用程序中通過監(jiān)聽這些廣播來得到各種系統(tǒng)的狀態(tài)信息

1. 動態(tài)注冊監(jiān)聽時間變化

新建一個類,繼承自 BroadcasterReceiver,并重寫父類的 onReceive() 方法,這樣當(dāng)有廣播來時,onReceive() 方法就會得到執(zhí)行

class MainActivity : AppCompatActivity() {

    lateinit var timeChangeReceiver: TimeChangeReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val intentFilter = IntentFilter()
        intentFilter.addAction("android.intent.action.TIME_TICK")
        timeChangeReceiver = TimeChangeReceiver()
        registerReceiver(timeChangeReceiver, intentFilter)
    }

    inner class TimeChangeReceiver : BroadcastReceiver() {

        override fun onReceive(context: Context?, intent: Intent?) {
            Toast.makeText(context, "Time has changed", Toast.LENGTH_SHORT).show()
        }
    }
}
  • 定義了一個內(nèi)部類 TimeChangeReceiver,繼承自 BroadcasterReceiver 并重寫父類的方法,這樣每當(dāng)系統(tǒng)時間發(fā)生變化時,就會使用 Toast 提示一段文本信息
  • 在 onCreate() 方法創(chuàng)建一個 IntentFilter 實例,添加值為 android.intent.action.TIME_TICK 的 action,這也是系統(tǒng)時間發(fā)生變化時,系統(tǒng)會發(fā)出的廣播的值
  • 創(chuàng)建 TimeChangeReceiver 實例,然后調(diào)用 registerReceiver() 方法進行注冊,將 IntentFilter 實例和 TimeChangeReceiver 實例傳進去,完成監(jiān)聽功能

2. 靜態(tài)注冊實現(xiàn)開機啟動

動態(tài)注冊的 BroadcasterReceiver 相對靈活,但必須在程序啟動后才能接收廣播,要想讓程序在未啟動的情況下也能接收廣播,就需要使用靜態(tài)注冊的方式

創(chuàng)建類 BootCompleteReceiver,Exported 屬性表示是否允許這個 BroadcasterReceiver 接收本程序以外的廣播,Enabled 屬性表示是否啟用這個 BroadcasterReceiver,勾選這兩個屬性,點擊 Finish 完成創(chuàng)建

class BootCompleteReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show()
    }
}

靜態(tài)的 BroadcasterReceiver 要在 AndroidManifest.xml 文件中注冊才可以使用。由于 Android 系統(tǒng)啟動完成后會發(fā)出一條值為 android.intent.action.BOOT_COMPLETED 的廣播,所以我們在 <receiver> 標(biāo)簽中添加一個 <intent-filter> 標(biāo)簽,并在里面聲明相應(yīng)的 action。另外,還必須在 AndroidManifest.xml 中進行權(quán)限聲明。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fragmenttest">
    
    <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/Theme.FragmentTest">
        
        ...
        
        <receiver
            android:name="com.example.broadcasttest.BootCompleteReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

發(fā)送自定義廣播

1. 發(fā)送標(biāo)準(zhǔn)廣播

新建一個 MyBroadcasterReceiver,并在 onReceive() 方法中加入如下代碼:

class MyBroadcasterReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "received in MyBroadcasterReceiver", Toast.LENGTH_SHORT).show()
    }
}

然后在 AndroidManifest.xml 中對這個 BroadcasterReceiver 進行修改

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fragmenttest">

	...
    
    <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/Theme.FragmentTest">
        
        ...
        
        <receiver
            android:name="com.example.broadcasttest.MyBroadcasterReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.broadcasttest.MyBroadcasterReceiver" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

接下來修改 activity_main.xml,定義一個按鈕,作為發(fā)送廣播的觸發(fā)點

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send Broadcast" />

</LinearLayout>

修改 MainActivity 中的代碼

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            val intent = Intent("com.example.broadcasttest.MyBroadcasterReceiver")
            intent.setPackage(packageName)
            sendBroadcast(intent)
        }
    }
}

這里對 setPackage() 方法做個說明,靜態(tài)注冊的 BroadcasterReceiver 是無法接收隱式廣播的,而默認(rèn)情況下我們發(fā)出的自定義廣播都是隱式廣播,因此這里要調(diào)用 setPackage() 方法,指定這條廣播是發(fā)送給哪個應(yīng)用程序的,從而讓它變成一條顯式廣播

2. 發(fā)送有序廣播

有序廣播是一種同步執(zhí)行的廣播,并且可以被截斷,我們再新建 AnotherBroadcasterReceiver

class AnotherBroadcasterReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "received in AnotherBroadcasterReceiver", Toast.LENGTH_SHORT).show()
    }
}

然后在 AndroidManifest.xml 中進行修改

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fragmenttest">

   ...

    <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/Theme.FragmentTest">
        
		...

        <receiver
            android:name="com.example.broadcasttest.AnotherBroadcasterReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.broadcasttest.MyBroadcasterReceiver" />
            </intent-filter>
        </receiver>
        
		...

    </application>

</manifest>

到目前為止,程序發(fā)出的都是標(biāo)準(zhǔn)廣播,要發(fā)送有序廣播,就要重新回到 BroadcasterTest 項目,然后修改 MainActivity 中的代碼

class MainActivity : AppCompatActivity() {
    
    ...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            val intent = Intent("com.example.broadcasttest.MyBroadcasterReceiver")
            intent.setPackage(packageName)
            sendOrderedBroadcast(intent, null)
        }
        ...
    }
}

sendOrderedBroadcast() 方法接收兩個參數(shù):第一個參數(shù)仍然是 Intent;第二個參數(shù)是一個與權(quán)限相關(guān)的字符串,這里傳入 null 即可

接下來設(shè)定 BroadcasterReceiver 的先后順序,修改 AndroidManifest.xml 中的代碼

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fragmenttest">

    ...

    <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/Theme.FragmentTest">
        <receiver
            android:name="com.example.broadcasttest.MyBroadcasterReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="100">
                <action android:name="com.example.broadcasttest.MyBroadcasterReceiver" />
            </intent-filter>
        </receiver>
        
        ...
        
    </application>

</manifest>

通過 android:priority 屬性給 BroadcasterReceiver 設(shè)置優(yōu)先級,優(yōu)先級比較高的 BroadcasterReceiver 就可以先收到廣播。既然 MyBroadcasterReceiver 獲得了接收廣播的優(yōu)先級,那么 MyBroadcasterReceiver 就可以選擇是否允許廣播繼續(xù)傳遞了

class MyBroadcasterReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "received in MyBroadcasterReceiver", Toast.LENGTH_SHORT).show()
        abortBroadcast()
    }
}

在 onReceive() 方法中調(diào)用 abortBroadcaster() 方法,就表示將這條廣播截斷,后面的 BroadcasterReceiver 將無法再接收這條廣播

到此這篇關(guān)于Android 零基礎(chǔ)到精通之廣播機制的文章就介紹到這了,更多相關(guān)Android 廣播機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論