概述
本文介紹兩種註冊方式的廣播:動態註冊( JAVA代碼
)、靜態( 在清單文件AndroidManifest.xml
中註冊)
動態註冊廣播接收器
達到的效果:在 app
的 MainActivity
中發送廣播消息的按鈕點擊後給出下面幾個反饋:
- 向
MainActivity
中的EditText
中寫入文字 - 彈出
Toast
- 打印
Logcat
創建項目的操作就略過了,下面開始每個模塊的製作以及代碼:
-
製作
MainActivity
的佈局文件acitvity_main
,其完整代碼如下:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:layout_gravity="center_horizontal" android:text="Received Broadcasts" /> <Button android:id="@+id/btnSendBroadcast" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:layout_gravity="center_horizontal" android:text="Send Broadcast"/> <EditText android:id="@+id/etReceivedBroadcast" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
-
製作
MainActivity
,其完整代碼如下:package com.ccsoft.broadcastdemo; import android.app.Activity; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity implements View.OnClickListener { MyReceiver myReceiver; IntentFilter intentFilter; EditText etReceivedBroadcast; Button btnSendBroadcast; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activit_main); etReceivedBroadcast = (EditText) findViewById(R.id.etReceivedBroadcast); btnSendBroadcast = (Button) findViewById(R.id.btnSendBroadcast); //keep reference to Activity context MyApplication myApplication = (MyApplication) this.getApplicationContext(); myApplication.mainActivity = this; btnSendBroadcast.setOnClickListener(this); myReceiver = new MyReceiver(); intentFilter = new IntentFilter("chanchawReceiver"); } @Override protected void onResume() { super.onResume(); registerReceiver(myReceiver, intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(myReceiver); } @Override public void onClick(View view) { Intent intent = new Intent("chanchawReceiver"); sendBroadcast(intent); } }
-
上面步驟貼到項目中後會有些類、對象不存在造成報錯,先彆着急,佈置完全部代碼後即可正常運行。步驟2中用到的
MyApplication
的完整代碼如下package com.ccsoft.broadcastdemo; import android.app.Application; public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); } MainActivity mainActivity; }
-
接收器
MyReceiver
的完整代碼如下:package com.ccsoft.broadcastdemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast; public class MyReceiver extends BroadcastReceiver { private static final String TAG = "chanchaw"; @Override public void onReceive(Context context, Intent intent) { MainActivity mainActivity = ((MyApplication) context.getApplicationContext()).mainActivity; mainActivity.etReceivedBroadcast.append("broadcast: "+intent.getAction()+"\n"); String msg = intent.getStringExtra("msg"); Toast.makeText(context, "接收到了!", Toast.LENGTH_LONG).show(); Log.i(TAG,"接收到廣播的消息了!"); } }
-
項目的清單文件
AndroidManifest.xml
的完整代碼如下:<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ccsoft.broadcastdemo"> <application android:name=".MyApplication" 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=".MainActivity" android:label="MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name="com.ccsoft.broadcastdemo.MyReceiver" > <intent-filter> <action android:name="chanchawReceiver" /> </intent-filter> </receiver> </application> </manifest>
- 最終形成的項目結構如下圖:
代碼解釋
執行完上面的步驟,所有代碼就都貼完了,下面來介紹下必要的知識點。類 MyApplication
用來綁定整個應用的實例,所以要在清單文件 AndroidManifest.xml
的 application
標籤中設置屬性 android:name=".MyApplication"
,該類中聲明瞭 MainActivity
類型的一個變量,並且在該頁面的 onCreate
事件中綁定該變量:
MyApplication myApplication = (MyApplication) this.getApplicationContext();
myApplication.mainActivity = this;
有了上面的準備工作才能在接收器類 MyReceiver
中使用它進而給 MainActivity
中的控件賦值,那麼本方法也就是實現 “控制反轉” - 我自己這麼叫 - 在接收器的邏輯中可以修改其他 Activity
中的數據。
靜態註冊方式
這裏還是要吐槽下的,看的資料年代久遠,導致一開始靜態註冊方式一直測試不通過,後來才發現原來 Android 8
之後修改了靜態註冊方式的使用方法,上面的 MainActivity
中點擊按鈕發送廣播的代碼中要設置接收器的包名,之後接收器才能接受到廣播,即按鈕點擊事件的完整代碼應該是:
@Override
public void onClick(View view) {
Intent intent = new Intent("chanchawReceiver");
intent.setPackage("com.ccsoft.broadcastdemo");
sendBroadcast(intent);
}
同時記得將 MainActivity
中的重載方法 onResume
、onPause
註釋掉 - 這兩個方法是動態註冊時纔用到。簡單修改後即將 “ 動態註冊方式 ” 修改爲 “ 靜態註冊方式 ” 了。