在Android开发中巧妙使用观察者模式避免内存泄露

发生内存泄露的场景:
场景1:静态变量引用Activity对象
场景2:静态View
场景3:内部类和匿名类
场景4:Handler
场景5:Threads和TimerTask
场景6:监听器
场景7:静态集合对象引起的泄漏
场景8:资源对象未关闭
场景9:使用对象池避免频繁创建对象
场景10:Back键退出引起的泄漏

现在有这么一个场景(场景3|场景6):在Activity里定义了一个Listener,这个Listener的实例需要以参数的形式传递到SDK里,SDK执行完耗时的操作(比如扫描蓝牙),然后执行该Listener的回调方法。这样一来,在扫描的过程中,如果我们按了返回键,Activity并不能正常销毁,因为SDK拥有Listener的强引用,这样就发生了内存泄露。
解决方法:
1. SDK提供了停止耗时操作的接口,那么在销毁Actiivity的时候调用该接口停止耗时操作即可。
2. 假设没有提供相关接口,可使用观察者模式解决:
①编写一个被观察者接口:

/**
 * Created by zhanzc on 2017/7/18.
 * 被观察者
 */
public interface IObservable {
    void update();
}

②编写一个观察者:

/**
 * Created by zhanzc on 2017/7/18.
 * 观察者类
 */
public class DataWatcher {

    private static DataWatcher dataWatcher;
    private DataWatcher(){}
    public static DataWatcher getInstance() {
        if (dataWatcher == null) {
            initWatcher();
        }

        return dataWatcher;
    }

    private static synchronized void initWatcher() {
        if (dataWatcher == null) {
            dataWatcher = new DataWatcher();
        }
    }

    // 一般来说,这应该是一个集合,但我这里只监听可能发生内存泄露的Activity,所以只用了一个observable
    private IObservable observable;

    /**
     * 添加被观察者
     * @param observable
     */
    public void register(IObservable observable) {
        this.observable = observable;
    }

    /**
     * 解除监听
     */
    public void unregister(IObservable ob) {
        this.observable = null;
    }

    /**
     * 通知被观察者更新数据
     */
    public void notifyObservable() {
        if (this.observable != null) {
            this.observable.update();
        }
    }
}

③Activity实现接口成为被观察者,实现相关方法:

@Override
public void update() {
    // 更新UI
}

④onCreate()方法执行

// 观察者观察被观察者
DataWatcher.getInstance().register(this);

⑤Linstener的class定义为static

⑥Listener的回调里调用:

// 通知被观察者更新数据
DataWatcher.getInstance().notifyObservable();

⑦onDestroy()执行:

// 解除观察
DataWatcher.getInstance().unregister(this);

如果你的项目引入了EventBus或RxJava等有订阅/被订阅关系的框架,也可以直接使用,操作都一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ithouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值