欢迎光临
梦想从学习开始!

你并不一定要用弱引用来避免内存泄漏| 小熊测试

本文主要介绍 你并不一定要用弱引用来避免内存泄漏| 小熊测试,小熊希望对大家的学习或者工作具有一定的参考学习价值,在测试领域有所提升和发展。

  我的一个同事最近提到他们看的一个演讲,其中讲到:

  如果你是一个安卓开发者却不使用弱引用,那么你就有麻烦了。

  我个人认为这不仅是一种错误观点,而且相当误导人。WeakReference(弱引用)应该是修复内存泄漏的最后手段。

  然后今天,我看到了 Enrique López Ma?as 发布在Google Developers Experts专栏的一篇文章。

  Finally understanding how references work in Android and Java

  A few weeks ago I attended Mobiconf, one of the best conferences for Mobile Developers I had the pleasure to attend in…medium.com

  这是一篇总结Java引用的好文章。

  这篇文章并没有说必须使用弱引用,但是也没有给出替代的方案。我觉得我必须给出其它的方法来阐明弱引用并不是必须使用。

  如果你不使用弱引用并不会真的有什么问题

  我认为处处使用弱引用并不是一种最佳实践。使用弱引用来修复内存泄漏的问题往往意味着缺乏合理的架构。

  虽然文章中给出的例子修复了潜在的内存泄漏问题,但是也有其它的方法。我可以给出两个耗时后台任务中避免内存泄漏的例子。

  避免AsyncTask内存泄漏的简单例子:

  Activity:

public class MainActivity extends Activity {

private MyAsyncTask task;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

task = new MyAsyncTask();

task.setListener(createListener());

task.execute();

}

@Override

protected void onDestroy() {

task.setListener(null);

super.onDestroy();

}

private MyAsyncTask.Listener createListener() {

return new MyAsyncTask.Listener() {

@Override

public void onSuccess(Object object) {

// adapt contents

}

};

}

}

  这里是AsyncTask:

classMyAsyncTaskextendsAsyncTask{

privateListenerlistener;

@Override

protectedObjectdoInBackground(Object[]params){

returndoSomeStuff();

}

privateObjectdoSomeStuff(){

//dosomethingtogetresult

returnnewObject();

}

@Override

protectedvoidonPostExecute(Objectobject){

if(listener!=null){

listener.onSuccess(object);

}

}

publicvoidsetListener(Listenerlistener){

this.listener=listener;

}

interfaceListener{

voidonSuccess(Objectobject);

}

}

  当然这个例子非常基础,但是我认为作为另一种解决方案的演示来说足够了。

  这里是另一个使用RxJava实现的简单例子,我们仍然没有使用弱引用。

public class MainActivity extends Activity {

private Subscription subscription;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

subscription = Observable

.fromCallable(new Callable<Object>() {

@Override

public Object call() throws Exception {

return doSomeStuff();

}

})

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Action1<Object>() {

@Override

public void call(Object o) {

// adapt contents

}

});

}

private Object doSomeStuff() {

//do something to get result

return new Object();

}

@Override

protected void onDestroy() {

subscription.unsubscribe();

super.onDestroy();

}

}

  注意如果我们没有unsubscribe Subscription那么仍然可能会出现内存泄漏。

  最后我给出两个Novoda的项目,它们是很好的学习资源。你可能猜到了,它们并没有使用任何弱引用:)。

  novoda/bonfire-firebase-sample

  bonfire-firebase-sample – An app to discuss your favourite emojis. This is a sample app built with Firebase.github.com

  novoda/spikes

  spikes – Where ideas & concepts are born & incubatedgithub.com

  我认为一个很重要的守则是让内部类为静态的。尤其是它们要做耗时的后台任务的时候。或者更好的方法是把这个类移到外面作为单独的类。

  用非静态的内部类做耗时的后台任务总是很糟糕的实践,不光是在安卓中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小熊分享邦(www.xxfxb.com),希望大家能坚持软件测试之路,谢谢。

赞(0) 打赏
未经允许不得转载:小熊分享邦 » 你并不一定要用弱引用来避免内存泄漏| 小熊测试

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏