关于项目中Toast的封装

关于项目中Toast的封装
image.png

前言


  • 在Android开发中,Toast是最常见的提示方式了,但是在实际开发中,如果直接使用Toast还是相对比较复杂的:

    Toast.makeText(context, R.string.text, Toast.LENGTH_SHORT).show();
    
  • 写这么长的代码还是要花点时间的,那么接下来我们就要聊聊如何简化。

思路


  • 说到简化,第一个反应当然是封装成工具类了,就像这样:

      public class ToastUtil {
              private ToastUtil(){}
    
              public static void showToast(@NonNull Context context, String text) {
                      Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
              }
      }
    
  • 这是最普遍的做法了,但是这样做同样也有问题,如果在我们需要弹Toast的地方,没有Context对象呢?

  • 这里我们就要看Toast所需要的这个上下文对象,Toast对这个对象没有任何要求,也就是说,仅仅需要一个上下文对象而已,那么,我们是不是可以直接保存下一个一直存在的Context对象,所以的Toast都使用这一个对象。

实现


  • 说到Android中一直存在的Context对象,大家会想到什么呢?没错,就是Application。

  • 下面是完整代码:

      public class ToastUtil{
    
              private Context mContext; // 上下文对象
    
              private ToastUtil(){} // 私有化构造
    
              private static final class Helper { // 内部帮助类,实现单例
                      static final ToastUtil INSTANCE = new ToastUtil();
              }
    
              public static ToastUtil getInstance() { // 获取单例对象
                      return Helper.INSTANCE;
              }
    
              public static void init(@NonNull Context context){ // 初始化Context
                      Helper.INSTACE.mContext = context;
              }
    
              public void showToast(@StringRes int strResID) { // 根据资源id弹Toast
                  if (mContext == null) {
                      throw new RuntimeException("Please init the Context before showToast");
                  }
                  showToast(mContext.getResources().getText(strResID));
              }
    
              public void showToast(CharSequence str) { // 根据字符串弹Toast
                  if (mContext == null) {
                      throw new RuntimeException("Please init the Context before showToast");
                  }
                  Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show();
              }
      }
    
  • 在Application中初始化

      public class MyApplication extends Application {
    
          @Override
          public void onCreate() {
              super.onCreate();
              ToastUtil.init(this);
          }
      }
    
  • 在任意类中使用:

      ToastUtil.getInstance().showToast("弹Toast!");
    

总结


  • 怎么样,这样封装后是不是很方便,如果你有其他的需求,也可以在工具类中添加方法。
  • 也许有人会说啦,你把一个Context对象保存在静态类中会不会造成内存泄漏啊?从技术角度说,这的确是内存泄漏,但是实际上我建议在Application中进行初始化,因为Application也是一个Context对象,而这个对象是存在于应用的整个生命周期的,所以并没有任何影响。
  • 当然啦,如果你非要在其他地方初始化ToastUtil,的确会造成内存泄漏。