一對多的統一監聽 —— 這就是 觀察者模式(Observer Pattern) 的經典應用場景。
也就是說:
一個事件源(Subject) → 可以注冊多個監聽器(Observers);
當事件發生時,一次性通知所有監聽器;
各監聽器通過統一的接口接收回調。
🔧 Java 示例代碼
import java.util.ArrayList;
import java.util.List;// 統一監聽接口(Observer)
interface EventListener {void onEvent(String event);
}// 事件源(Subject)
class EventSource {private final List<EventListener> listeners = new ArrayList<>();// 添加監聽器public void addListener(EventListener listener) {listeners.add(listener);}// 移除監聽器public void removeListener(EventListener listener) {listeners.remove(listener);}// 觸發事件,通知所有監聽器public void triggerEvent(String event) {System.out.println("EventSource: 觸發事件 -> " + event);for (EventListener listener : listeners) {listener.onEvent(event);}}
}// 具體監聽器 A
class LoggingListener implements EventListener {@Overridepublic void onEvent(String event) {System.out.println("LoggingListener 收到事件: " + event);}
}// 具體監聽器 B
class AlertListener implements EventListener {@Overridepublic void onEvent(String event) {System.out.println("AlertListener 收到事件: " + event);}
}// 測試
public class ObserverPatternDemo {public static void main(String[] args) {EventSource source = new EventSource();// 注冊多個監聽器source.addListener(new LoggingListener());source.addListener(new AlertListener());source.addListener(event -> System.out.println("匿名Listener 收到事件: " + event));// 觸發事件source.triggerEvent("用戶登錄");source.triggerEvent("文件上傳");}
}
?? 輸出結果
EventSource: 觸發事件 -> 用戶登錄
LoggingListener 收到事件: 用戶登錄
AlertListener 收到事件: 用戶登錄
匿名Listener 收到事件: 用戶登錄EventSource: 觸發事件 -> 文件上傳
LoggingListener 收到事件: 文件上傳
AlertListener 收到事件: 文件上傳
匿名Listener 收到事件: 文件上傳
📌 總結
一對多的統一監聽 就是 觀察者模式:
Subject(事件源):維護監聽器集合;
Observer(監聽器):實現統一回調接口;
Notify(通知):事件觸發時,循環回調所有監聽器。
這樣做的好處是:
解耦(事件源無需關心監聽器的實現細節);
擴展性好(隨時新增/刪除監聽器);
統一接口(所有監聽器用一個回調方法
onEvent
處理)。
Android 里到處都是“一對多統一監聽”這種觀察者模式的實例,幾乎是 核心設計思想之一。下面列幾個典型的例子給你:
📌 Android 中的一對多統一監聽實例
1. View 的點擊事件分發
事件源(Subject):
View
監聽器(Observer):
OnClickListener
但這里是 一對一,只能設置一個
OnClickListener
。
👉 不過在 事件總線/廣播里是一對多。
2. BroadcastReceiver(廣播機制)
這是 Android 里 最標準的一對多統一監聽:
事件源:系統/應用發送的廣播(Intent)。
觀察者:所有注冊的
BroadcastReceiver
。當廣播觸發時,系統會依次通知所有匹配的接收者。
// 注冊廣播接收器
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {int level = intent.getIntExtra("level", 0);System.out.println("收到電量變化廣播: level=" + level);}
}, filter);// 任意地方發廣播
Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.putExtra("level", 90);
sendBroadcast(intent);
👉 所有監聽 ACTION_BATTERY_CHANGED 的接收器都會同時收到回調。
3. LiveData / Flow / RxJava
事件源:
LiveData<T>
觀察者:
Observer<T>
你可以給同一個 LiveData 添加多個觀察者,它們會同時收到數據更新。
MutableLiveData<String> liveData = new MutableLiveData<>();// 監聽器1
liveData.observe(this, data -> {Log.d("Observer1", "收到數據: " + data);
});// 監聽器2
liveData.observe(this, data -> {Log.d("Observer2", "收到數據: " + data);
});// 觸發事件
liveData.setValue("新消息來了!");
👉 輸出:
Observer1: 收到數據: 新消息來了!
Observer2: 收到數據: 新消息來了!
4. RecyclerView.AdapterDataObserver
事件源:
RecyclerView.Adapter
觀察者:
AdapterDataObserver
當數據集變化時,會通知所有觀察者(例如 RecyclerView 自己 + 其他訂閱者)。
RecyclerView.Adapter adapter = ...;
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {@Overridepublic void onChanged() {Log.d("Observer", "Adapter 數據更新");}
});// 更新數據
adapter.notifyDataSetChanged();
5. ContentObserver
事件源:ContentProvider 數據變化。
觀察者:所有注冊的
ContentObserver
。
getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,true,new ContentObserver(new Handler()) {@Overridepublic void onChange(boolean selfChange) {Log.d("Observer", "相冊數據變化了!");}}
);
? 總結
在 Android 里,一對多統一監聽(觀察者模式)的典型實現有:
BroadcastReceiver(廣播機制)
LiveData.observe()
RecyclerView.AdapterDataObserver
ContentObserver
EventBus/Flow/RxJava 等
這些都屬于 統一監聽回調的一對多場景。
在 Android 開發里,觀察者模式(Observer Pattern)非常常見,主要用于 “一對多”通知的場景:當一個對象(被觀察者/Subject)狀態變化時,會自動通知所有依賴它的對象(觀察者/Observer),從而實現解耦。
🔹 為什么要用觀察者模式?
解耦合:觀察者不需要知道被觀察者的內部實現,只關心變化。
靈活擴展:可以隨時增加/移除觀察者,不需要修改被觀察者邏輯。
統一通知機制:避免手動在多個地方寫重復的刷新或回調。
🔹 在 Android 中常見的使用場景
1. UI 更新和數據監聽
LiveData + Observer(Jetpack):UI 組件(Activity/Fragment)訂閱數據,數據變化時自動刷新 UI。
EventBus/RxJava:跨組件事件傳遞,類似全局觀察者模式。
2. 自定義組件封裝
例如封裝一個 網絡狀態監聽組件:
被觀察者:
NetworkManager
(內部監聽系統廣播/ConnectivityManager)。觀察者:Activity/Fragment/自定義 View,需要知道網絡是否可用。
這樣多個頁面只要注冊為觀察者,就能統一收到網絡變化通知。
3. 多模塊通信
下載/上傳進度監聽:下載器作為 Subject,UI 頁面作為 Observer。
播放器狀態監聽:MediaPlayer/ExoPlayer 的狀態變化通知給 UI 控件(進度條、播放按鈕)。
4. 數據緩存和刷新
比如 Room + LiveData 就是典型觀察者模式:數據庫數據變更 → LiveData 通知 → UI 自動刷新。
🔹 簡單封裝示例
假設我們封裝一個 全局事件中心,支持任意組件監聽和通知。
// 1. 定義觀察者接口
public interface Observer<T> {void onUpdate(T data);
}// 2. 被觀察者(事件中心)
public class EventBus<T> {private final List<Observer<T>> observers = new ArrayList<>();public void register(Observer<T> observer) {observers.add(observer);}public void unregister(Observer<T> observer) {observers.remove(observer);}public void notifyObservers(T data) {for (Observer<T> observer : observers) {observer.onUpdate(data);}}
}// 3. 使用示例
public class NetworkManager {private static final EventBus<Boolean> eventBus = new EventBus<>();public static void addNetworkObserver(Observer<Boolean> observer) {eventBus.register(observer);}public static void removeNetworkObserver(Observer<Boolean> observer) {eventBus.unregister(observer);}// 系統監聽到網絡變化時調用public static void onNetworkChanged(boolean available) {eventBus.notifyObservers(available);}
}
在 Activity 中用法:
public class MainActivity extends AppCompatActivity {private final Observer<Boolean> networkObserver = available -> {Toast.makeText(this, available ? "網絡可用" : "網絡不可用", Toast.LENGTH_SHORT).show();};@Overrideprotected void onStart() {super.onStart();NetworkManager.addNetworkObserver(networkObserver);}@Overrideprotected void onStop() {super.onStop();NetworkManager.removeNetworkObserver(networkObserver);}
}
這樣就實現了一個簡單的觀察者封裝:
解耦:NetworkManager 不關心誰在監聽。
可復用:任意頁面都能監聽網絡變化。
🔹 總結
在 Android 里,觀察者模式適用于:
數據驅動 UI(LiveData、Flow、RxJava)
組件通信(EventBus、全局狀態監聽)
自定義控件封裝(播放器、下載器、網絡監控等)
👉 適合所有 “一個地方變化,多個地方要響應” 的場景。