彻底理解引用在 Android 和 Java 中的工作原理

本文讲的是彻底理解引用在 Android 和 Java 中的工作原理,

  • 澳门新葡亰手机版,原文地址:Finally understanding how references work in Android
    and
    Java

几周前,我很荣幸地参加了在波兰举行的 Mobiconf
,移动开发者参加的最好的研讨会之一。我的朋友兼同事 Jorge Barroso
做了个名为“最好的做法”的演说 ,这让我在听后很有感触:

  • 原文作者:Enrique López
    Mañas
  • 译文出自:掘金翻译计划
  • 译者:jacksonke
  • 校对者:jamweak,PhxNirvana

对于一个 Android 开发者,如果你不使用 WeakReferences,这是有问题的。

几周前,我很荣幸地参加了在波兰举行的Mobiconf,移动开发者参加的最好的研讨会之一。我的朋友兼同事
Jorge Barroso
做了个名为“最好(良好)的做法”的演说 ,这让我在听后很有感触:

举个恰当的例子,几个月前,我发布了我的最后一本书 “Android High
Performance”, 联席作者是 Diego Grancini。最热门的章节之一就是讨论
Android
的内存管理。在本章中,我们介绍了移动设备中内存的工作原理,内存泄漏是如何发生的,为什么这个是重要的,以及我们可以应用哪些技术来避开它们。因为我从开发
Android
起,就常常看到这么种倾向:轻视甚至无视一切与内存泄漏和内存管理相关的问题。已经满足开发需求了,为何要庸人自扰呢?我们总是急于开发新的功能,我们宁愿在下一个
Sprint
演示中呈现一些可见的东西,也不会关心那些没有人一眼就能看到的东西。

对于一个 Android 开发者,如果你不使用 WeakReferences,这是有问题的。

这无疑是导致技术债务一个活生生的例子。
我甚至可以补充地说,技术债务在现实世界中也有一些影响,那是我们不能用单元测试衡量的:失望,开发者间的摩擦,低质量的软件和积极性的丧失。这种影响难以衡量的原因是在于它们常常发生在长远的将来的某个时间点。这有点像政客:如果我只当政
8 年,为何我要烦心 12
年后将要发生的事呢?除了在软件开发,一切都以更快的方式。

举个恰当的例子,几个月前,我发布了我的最后一本书 “Android High
Performance”,
联席作者是 Diego
Grancini。最热门的章节之一就是讨论
Android
的内存管理。在本章中,我们介绍了移动设备中内存的工作原理,内存泄漏是如何发生的,为什么这个是重要的,以及我们可以应用哪些技术来避开它们。因为我从开发
Android
起,就常常看到这么种倾向:轻视甚至无视一切与内存泄漏和内存管理相关的问题。已经满足开发需求了,为何要庸人自扰呢?我们总是急于开发新的功能,我们宁愿在下一个斯普林特演示中呈现一些可见的东西,也不会关心那些没有人一眼就能看到的东西。

编写软件开发中应该采纳的设计思想可能需要一些大篇文章,而且已经有很多书和文章可供您参考。然而,简要地解释不同类型的内存引用,它们具体是什么,以及如何在
Android 中使用,这是个相对简短的任务,这也是我想在本文中做的。

这无疑是导致技术债务一个活生生的例子。
我甚至可以补充地说,技术债务在现实世界中也有一些影响,那是我们不能用单元测试衡量的:失望,开发者间的摩擦,低质量的软件和积极性的丧失。这种影响难以衡量的原因是在于它们常常发生在长远的将来的某个时间点。这有点像政客:如果我只当政
8 年,为何我要烦心 12
年后将要发生的事呢?除了在软件开发,一切都以更快的方式。

首先:Java 中的引用是什么?

编写软件开发中应该采纳的设计思想可能需要一些大篇文章,而且已经有很多书和文章可供您参考。然而,简要地解释不同类型的内存引用,它们具体是什么,以及如何在
Android 中使用,这是个相对简短的任务,这也是我想在本文中做的。

引用指向了一个对象,你能通过引用访问对象。

首先:Java 中的引用是什么?

Java 默认有 4 种类型的引用:强引用、软引用、弱引用
和虚引用。部分人认为只有强引用和弱引用两种类型的引用,而弱引用有两个层次的弱化。我们习惯于将生活中的一切事物归类,那种毅力堪比植物学家对植物的分类的。不论你觉得哪种分类更好,首先你需要去理解这些引用。然后你可以找出自己的分类。

引用指向了一个对象,你能通过引用访问对象。

各种引用都是什么意思?

Java 默认有 4
种类型的引用:强引用(StrongReference)软引用(SoftReference)弱引用(WeakReference)

虚引用(PhantomReference)。部分人认为只有强引用和弱引用两种类型的引用,而弱引用有两个层次的弱化。我们习惯于将生活中的一切事物归类,那种毅力堪比植物学家对植物的分类的。不论你觉得哪种分类更好,首先你需要去理解这些引用。然后你可以找出自己的分类。

StrongReference: 强引用是 Java
中最为常见的引用类型。任何时候,当我们创建了一个对象,强引用也同时被创建了。比如,当我们这么做:

各种引用都是什么意思?

MyObject object = new MyObject();

StrongReference: 强引用是 Java
中最为常见的引用类型。任何时候,当我们创建了一个对象,强引用也同时被创建了。比如,当我们这么做:

一个新的 MyObject 对象被创建,指向它的强引用保存在 object
中。你还在看吧? 嗯,更有意思的事情来了,这个 object
是可以强行到达的——意思就是,它可以通过一系列强引用找到,这将会阻止垃圾回收机制回收它,然而,这正是是我们最想要的。现在,我们来看个例子。

MyObject object = new MyObject();

花几分钟,尝试去找可能出现问题的点。

一个新的 MyObject 对象被创建,指向它的强引用保存在 object
中。你还在看吧? 嗯,更有意思的事情来了,这个 object
是可以强行到达的——意思就是,它可以通过一系列强引用找到,这将会阻止垃圾回收机制回收它,然而,这正是是我们最想要的。现在,我们来看个例子。

不用担心,如果一时找不到,那再花点时间看看。

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        new MyAsyncTask().execute();
    }

    private class MyAsyncTask extends AsyncTask {
        @Override
        protected Object doInBackground(Object[] params) {
            return doSomeStuff();
        }
        private Object doSomeStuff() {
            //do something to get result
            return new MyObject();
        } 
    }
}

现在呢?

花几分钟,尝试去找可能出现问题的点。

AsyncTask 对象会在 Activity onCreate()
方法中创建并运行。但这里有个问题:内部类在它的整个生命周期中是会访问外部类。

不用担心,如果一时找不到,那再花点时间看看。