开启生长之旅!这是我参加「日新计划 2 月更文应战」的第 7 天,点击查看活动概况

前语

起因

今日开发遇到一个问题,便是在快速点击带点击事件的控件,假如控件里面写的是Dialog弹窗就有概率呈现弹窗接连在界面上呈现两次,也便是你关闭弹窗后发现还有一个相同的弹窗在界面,这样就会带来不好的体会。

结果

2月9日

在网上查了许多解决办法,就有说到将该Dialog变成类的成员变量,不用每次都new就或许防止这种情况呈现,但我着实不清楚为什么以及详细怎么做,所以请教了组里的大哥,大哥和我说他之前也处理过这种问题,运用了弱引证,可我仍是不知道详细的实现方式,所以便找到大哥的代码,并在网上了解了弱引证的详细作用。

2月10日

今日我请教了咱们开发群的Java大佬,他告诉我,我这个写法仍然防止不了弹两次Dialog的,并给出定见,能够运用同享状态,引荐我创立一个同享的ReentrantLock,不过我还没去实现,等有时刻再看看。

下面就让咱们看看弱引证到底是什么。

正篇

弱引证的概念

想知道弱引证,那就得知道几个名词:

  • 强引证
  • 软引证
  • 弱引证
  • 虚引证

首要咱们来看看这些词的概念:

  1. 强引证

强引证(StrongReference):最传统的“引证”的界说,是指在程序代码之中普遍存在的引证赋值,即相似“Object obj = new Object()”这种引证联系。不管任何情况下,只需强引证联系还存在,废物搜集器就永远不会收回掉被引证的目标。

  1. 软引证

软引证(SoftReference):在体系即将发生内存溢出之前,将会把这些目标列入收回范围之中进行第二次收回。假如这次收回后还没有满足的内存,才会抛出内存流出反常。

  1. 弱引证

弱引证(WeakReference):被弱引证相关的目标只能生计到下一次废物搜集之前。当废物搜集器作业时,不管内存空间是否满足,都会收回掉被弱引证相关的目标。

  1. 虚引证

虚引证(PhantomReference):一个目标是否有虚引证的存在,彻底不会对其生计时刻构成影响,也无法经过虚引证来获得一个目标的实例。为一个目标设置虚引证相关的唯一意图便是能在这个目标被搜集器收回时收到一个体系通知。

以上界说都是参阅自知乎答复 :强引证、软引证、弱引证、虚引证有什么区别?详细运用场景是什么? – 知乎 (zhihu.com),从这咱们能够了解到其实咱们Java中new目标便是强引证,强引证的目标是可触及的,废物搜集器就永远不会收回掉被引证的目标,也就简而言之目标在引证时,不收回,上面说的文章中也举例说明了强引证的特色:

安卓开发基础——弱引用的使用

而咱们本篇说的弱引证,则是发现即收回,它一般是用来描绘那些非必需目标,只被弱引证相关的目标只能生计到下一次废物搜集发生为止。在体系GC时,只需发现弱引证,不管体系堆空间运用是否足够,都会收回掉只被弱引证相关的目标。

但是,又由于废物收回器的线程一般优先级很低,所以,一般并不一定能很快地发现持有弱引证的目标,而在这种情况下,弱引证目标就能够存在较长的时刻。

而如何运用弱引证,咱们接着往下看:

运用办法

前语说到咱们运用了弱引证在开发中大哥已经运用过,所以我就跟着后面仿写一下就好,而知乎的那篇文章也说到:

安卓开发基础——弱引用的使用

这就基本是弱引证的界说办法,由于之前前语说的Dialog问题弱引证并没有真实起效果,所以咱们换一种办法去展示他在安卓上的运用,那便是在运用Bitmap时防止OOM,写法如下:

ImageView imageView = findViewById(R.id.vImage);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background);
Drawable drawable = new BitmapDrawable(getResources(), bitmap);
WeakReference<Drawable> weakDrawable = new WeakReference<>(drawable);
Drawable bgDrawable = weakDrawable.get();
if(bgDrawable != null) {
    imageView.setBackground(drawable);
}

咱们再对比一下一般的强引证办法:

ImageView imageView = findViewById(R.id.vImage);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background);
Drawable drawable = new BitmapDrawable(getResources(), bitmap);
imageView.setBackground(drawable);

其实,便是对drawable目标从强引证转为弱引证,这样一旦呈现内存不足,不会直接去运用drawable目标,让JVM自动收回这些缓存图片目标所占用的空间,从而有效地防止了OOM的问题。

总结

其实这块内容需要对GC机制很熟悉,我不是很熟,所以运用或许也呈现不对,希望读者能够积极纠正,谢谢观看!