如何在Android Studio中自定义实现观察者模式,将Activity作为被观察者
核心问题澄清
- 绝对不要手动创建Activity实例:Android四大组件的实例均由系统负责创建与生命周期调度,自行new出的MainActivity没有和系统上下文绑定,属于完全无效的空对象,会直接引发崩溃、内存泄漏等问题,该实现思路不可行。
- Activity可以作为被观察者,但需要严格遵守Android生命周期规则,观察者必须在对应生命周期主动完成订阅/取消订阅操作,避免持有已经销毁的Activity引用。如果你的场景需要跨多个Activity分发事件,更推荐将被观察者抽为全局单例管理类,和具体Activity解耦,不受单个页面生命周期影响。
最简观察者模式实现方案
步骤1:定义基础接口
首先定义观察者和被观察者的通用接口:
// 观察者接口 public interface UrlObserver { void onUrlGenerated(String url); }
// 被观察者接口 public interface UrlSubject { void registerObserver(UrlObserver observer); void removeObserver(UrlObserver observer); void notifyObservers(String url); }
步骤2:实现全局单例被观察者
将事件分发逻辑抽为单例管理类,避免和具体页面耦合:
public class UrlEventManager implements UrlSubject { private static volatile UrlEventManager INSTANCE; private final List<UrlObserver> observerList = new ArrayList<>(); private UrlEventManager() {} public static UrlEventManager getInstance() { if (INSTANCE == null) { synchronized (UrlEventManager.class) { if (INSTANCE == null) { INSTANCE = new UrlEventManager(); } } } return INSTANCE; } @Override public void registerObserver(UrlObserver observer) { if (!observerList.contains(observer)) { observerList.add(observer); } } @Override public void removeObserver(UrlObserver observer) { observerList.remove(observer); } @Override public void notifyObservers(String url) { for (UrlObserver observer : observerList) { observer.onUrlGenerated(url); } } }
步骤3:MainActivity触发事件
用户点击按钮生成URL后,直接调用单例类完成事件分发:
public class MainActivity extends AppCompatActivity { private EditText inputEt; private Button jumpBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); inputEt = findViewById(R.id.input_et); jumpBtn = findViewById(R.id.jump_btn); jumpBtn.setOnClickListener(v -> { String inputContent = inputEt.getText().toString().trim(); // 自定义生成URL的逻辑 String generatedUrl = "https://example.com/?content=" + Uri.encode(inputContent); // 分发事件给所有观察者 UrlEventManager.getInstance().notifyObservers(generatedUrl); // 跳转到Activity1 startActivity(new Intent(this, Activity1.class)); }); } }
步骤4:观察者页面实现订阅
以Activity1为例,所有需要接收URL的页面都实现UrlObserver接口,同时在生命周期中完成订阅和取消订阅操作:
public class Activity1 extends AppCompatActivity implements UrlObserver { private TextView showUrlTv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_1); showUrlTv = findViewById(R.id.show_url_tv); } @Override protected void onStart() { super.onStart(); // 订阅事件 UrlEventManager.getInstance().registerObserver(this); } @Override protected void onStop() { super.onStop(); // 必须取消订阅,避免内存泄漏 UrlEventManager.getInstance().removeObserver(this); } @Override public void onUrlGenerated(String url) { // 更新UI展示URL showUrlTv.setText(url); } }
注意事项
- 如果你的场景仅需要跳转时传递一次数据,直接使用
Intent.putExtra()传递参数更简单,观察者模式更适合多订阅端、多频次事件更新的场景 - 所有观察者必须在页面销毁前主动取消订阅,避免内存泄漏
- 不要自行创建任何Android组件的实例,所有组件的生命周期都由系统统一调度
内容的提问来源于stack exchange,提问作者MUCHUAN SU
相关产品推荐
相关产品推荐

