android内存泄露:4、Toast的错误使用导致内存泄露

目录

一、前言

二、Toast的错误使用导致内存泄露

1、新建一个 Module,写主界面 MainActivity,布局 activity_main

2、写业务逻辑

3、效果展示

4、解决方案


一、前言

上篇文章我们介绍了:Handler的错误使用导致内存泄露详细可参考博文:原创 android内存泄露:3、Handler的错误使用导致内存泄露 ,这篇文章我们将介绍:Toast的错误使用导致内存泄露

二、Toast的错误使用导致内存泄露

我们通常,连续点击按钮多次提示的 Toast,它必须等待前面的 Toast显示完了,后面的才能显示出来。

这可能在某种情境下,不是我们想要的。

假如我们想要的结果是:当我点击多次按钮,必须把我最新的 Toast显示出来。

这个时候我们需要去写一个单例的 Toast,但是我们在写的时候,可能会导致我们 Activity的泄露。

1、新建一个 Module,写主界面 MainActivity,布局 activity_main

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void showToast(View view) {
        startActivity(new Intent(MainActivity.this, ToastActivity.class));
    }

}

activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="showToast"
        android:text="Toast的错误使用" />

</LinearLayout>

2、写业务逻辑

创建一个 Toast的工具类

public class ToastUtils {
    private static Toast sToast;

    public static void showToast(Context context, String msg) {
        if (sToast == null) {
            sToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        }

        sToast.setText(msg);
        sToast.show();
    }

}

ToastActivity

public class ToastActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toast);

        ToastUtils.showToast(this, new Date().getTime()+"");

    }

}

3、效果展示

类似上几篇文章,使用 LeakCanary工具,会测试到内存泄露的相关信息,这里就不截图和录视频了。

4、解决方案

/**
 * 如果我们的单例引用到了Activity,那么就会导致Activity无法被GC回收,从而导致内存泄露。
 *
 * 下面代码中sToast是静态的变量,其应用的对象不会被回收,sToast引用到了context,
 * 而 context可能就是Activity的实例,GC无法回收,因此造成Activity的泄露。
 */

解决方式:修改静态单例中对上下文的引用

public class ToastUtils {
    private static Toast sToast;

    public static void showToast(Context context, String msg) {
        if (sToast == null) {
            //sToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
            
            //我们让静态的Toast引用到全App唯一的一个Application的上下文对象即可
            sToast = Toast.makeText(context.getApplicationContext(), msg, Toast.LENGTH_SHORT);

        }

        sToast.setText(msg);
        sToast.show();
    }

}

有关 Android上下文 比较好的文章:

Android Context 上下文 你必须知道的一切_爱折腾的华哥的博客-CSDN博客

sToast 什么时候会被 GC 给回收掉?

sToast 它是一个静态变量,静态的变量属于字节码级别的,字节码一旦被加载了,一般就不会移除了。

加载字节码是类加载器的工作,那么它是不会被 GC 给回收掉的,除非程序退出。

在java里面,类加载器分了好几种,你可以去自定义一个类加载器,它继承于ClassLoader,

当我们自定义的类加载器被卸载掉后,所加载的静态类对象才会被移除掉。

默认情况下,我们都使用系统自带的类加载器,它加载的静态对象,是不会被GC回收掉的。

所以静态变量不是越多越好,它不能够被回收。

注意:

1、之所以不在调用时候改,是因为工具类解决更好,因为在使用过程中可能会忘记这一点

2、虽然不用 static可以避免这个问题,但调用 ToastUtils的时候有点麻烦了

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android中,有两种方式可以进行内存的读写操作。第一种是对于Android中的内部存储进行读写,可以使用File类和相关的读写方法来实现。通过创建File对象,你可以指定要读写的文件路径和文件名,然后使用相应的方法来读取或写入数据。 另一种是对于Android中的外部存储进行读写,可以使用类似的方法来实现。在这种情况下,你需要获得外部存储的访问权限,并使用Environment类提供的方法来获取外部存储的路径,然后再进行读写操作。 当然,在进行内存读写操作时,我们也要注意内存泄漏的问题。比如,在使用WebView时,如果没有正确处理WebView的生命周期,可能会导致内存泄漏。为了解决这个问题,我们可以在Activity中使用WeakReference来持有WebView,并在Activity销毁时释放WebView的资源。 另外,使用Handler和Toast时也需要注意避免内存泄漏。如果我们错误使用Handler或Toast,可能会导致它们持有Activity的引用而无法被释放,从而导致内存泄漏。为了解决这个问题,我们可以使用StaticInnerClass或者Handler的removeCallbacks方法来避免内存泄漏。 综上所述,Android中的内存读写操作可以通过File类和相关方法来实现,同时我们还需要注意内存泄漏的问题,特别是在使用WebView、Handler和Toast时要特别小心。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

被开发耽误的大厨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值