Android廣播機制(2)

發送自定義廣播

發送標準廣播

步驟

1.定義一個廣播接收器來接收此廣播,新建MyBroadcastReceiver,代碼以下:java

//當MyBroadcastReceiver收到自定義的廣播時,就會彈出"received in MyBroadcastReceiver"的提示
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
    }
}

2.註冊廣播,在AndroidManifest.xml中對這個廣播接收器進行修改:android

//讓MyBroadcastReceiver接收一條值爲com.example.broadcasttest.MY_BROADCAST的廣播,因此一會咱們發送的廣播就是這樣一條廣播
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
      ...
      <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>
      </application>
</manifest>

3.定義一個按鈕做爲廣播的觸發點,修改MainActivity的代碼:安全

public class MainActivity extends AppCompatActivity {
      ...
      @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button= (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent("com.example.a51104.broadcasttest.MY_BROADCAST");
                sendBroadcast(intent,null);//發送標準廣播,這樣全部監聽這條廣播的廣播接收器均可以接收到信息
            }
        });
      ...
    }
 ...
}

廣播是經過Intent傳遞的,因此也能夠攜帶其餘數據app

跨進程廣播

廣播是一種能夠跨進程的通訊方式。所以在咱們應用程序內發出的廣播,其餘的應用程序應該也是能夠收到的。
新建項目BroadcastTest2ide

步驟

1.建立廣播接收器this

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

2.修改AndroidManifest.xmlcode

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest2">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
      ...
       <receiver
            android:name=".AnotherBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.a51104.broadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>
      </application>
</manifest>

能夠看到AnotherBroadcastReceiver一樣接收的是com.example.a51104.broadcasttest.MY_BROADCAST這條廣播(可是這是兩個程序)
3.回到BroadcastTest中點擊觸發廣播的按鈕,發現兩次廣播都被接收了。
疑問:這裏建立的都是靜態註冊的廣播,若是是動態的呢?xml

發送有序廣播

回到BroadcastTest項目進程

1.修改MainActivity中代碼:ip

public class MainActivity extends AppCompatActivity {
      ...
      @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button= (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent("com.example.a51104.broadcasttest.MY_BROADCAST");
                 sendOrderedBroadcast(intent,null);//發送有序廣播,這樣全部監聽這條廣播的廣播接收器均可以接收到信息
            }
        });
      ...
    }
 ...
}

2.設置廣播接收器的前後順序,保證MyBroadcastReceiver必定比AnotherBroadcastReceiver先收到廣播,修改AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest2">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
      ...
        <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="100">
                <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>
      </application>
</manifest>

咱們經過android:priority設置了優先級,優先級越高的廣播接收器就更先接收到廣播。

3.爲了顯示有序廣播的特色,咱們在MyBroadcastReceiver中截斷廣播的傳播,使得AnotherBroadcastReceiver接收不到廣播,修改MyBroadcastReceiver代碼:

//在MyBroadcastReceiver onReceive中添加abortBroadcast()表示將這條廣播截斷
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
        abortBroadcast();
    }
}

使用本地廣播

前面咱們發送和接收的廣播權所有屬於系統全局廣播,即發出的廣播能夠被其餘任何應用程序接收到兒,而且咱們也能夠接受來自於其餘任何應用程序的廣播。這樣就很容易引發安全性的問題,好比說咱們發送的一些攜帶關鍵性數據的廣播頗有可能被其餘的應用程序截獲,或者其餘的程序不停地向咱們廣播接收器發送各類垃圾廣播。
爲了可以簡單的解決廣播的安全性問題,Android引入了一套本地廣播機制,使用這個機制,發車廣播只可以在應用程序內部進行傳遞,而且廣播接收器只能接收來自本應用程序發出的廣播,這樣全部的安全性問題就都不存在了。
本地廣播的用法並不複雜,主要是使用了一個LocalBroadcastManager來對廣播進行管理,並提供了發送廣播和註冊廣播接收器的方法。

實例

修改MainActivity中的代碼:

public class MainActivity extends AppCompatActivity {
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager=LocalBroadcastManager.getInstance(this);//獲取實例
        Button button= (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent("com.example.a51104.broadcasttest.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);//發送本地廣播
            }
        });
        intentFilter=new IntentFilter();
        intentFilter.addAction("com.example.a51104.broadcasttest.LOCAL_BROADCAST");
        localReceiver=new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);//註冊本地廣播監聽器
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }
    class LocalReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"received local broadcast",Toast.LENGTH_SHORT).show();
    }
}
}

其實大部分代碼都和動態註冊廣播接收器以及發送廣播的代碼是同樣的,可是註冊、發送廣播和取消註冊都是經過本地廣播管理器控制的。本地廣播管理經過LocalBroadcastManager.getInstance(this)獲取實例。這時這條廣播只會在這個應用程序內部傳遞。
注:本地廣播是沒法經過靜態註冊的方式來接收的。由於靜態註冊主要就是爲了讓程序在未啓動的狀況下也能收到廣播,而發送本地廣播時,咱們的程序是確定已經啓動了,所以也徹底不須要使用靜態註冊的功能。個人理解是由於須要建立本地廣播管理者,這個只能在程序中動態建立,因此廣播是經過動態註冊。

本地廣播的優點

  • 能夠明確地知道正在發送的廣播不會離開咱們的程序,所以沒必要須要擔憂機密數據的泄露。
  • 其餘的程序沒法將廣播發送到咱們程序的內部,所以不須要擔憂安全漏洞的隱患。
  • 發送本地廣播比發送系統全局廣播將會更加高效
相關文章
相關標籤/搜索