【问题标题】:Dealing with deprecated methods in android处理android中不推荐使用的方法
【发布时间】:2015-10-14 09:53:55
【问题描述】:


我目前正在构建一个面向 API 23 的应用,最低 API 为 19。
在 API 23 中,android.widget.TimePicker 组件的一些方法被替换了。

例如:

TimePicker.getCurrentHour();

被替换为:

TimePicker.getHour();

现在,在我的应用中使用 TimePicker 时,我应该使用以下 if 语句检查设备是否使用 API 22 或更高版本:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        TimePicker.getHour();
    else
        TimePicker.getCurrentHour();

我所做的是扩展 TimePicker 类并实现不推荐使用的方法,如下所示:

public class TimePicker extends android.widget.TimePicker {

    public TimePicker(Context context) {
        super(context);
    }

    public void setCurrentHour(int hour) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            super.setHour(hour);
        else
            super.setCurrentHour(hour);
    }

    public void setCurrentMinute(int minute) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            super.setMinute(minute);
        else
            super.setCurrentMinute(minute);
    }

    public int getCurrentHour() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            return super.getHour();
        else
            return super.getCurrentHour();
    }

    public int getCurrentMinute() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            return super.getMinute();
        else
            return super.getCurrentMinute();
    }
}

所以使用这个类的用户不会影响方法的改变(他应该只在他的实现中替换 TimePicker 类的导入)。

这样做是否正确?还是有更好的解决方案?

谢谢

【问题讨论】:

  • 这是个好办法。在我看来,你成功了! :) 也许你的方法应该以新的命名约定命名,当你放弃对 pre M 的支持时,使过渡更容易。
  • 嘿,这个 .M 是关于什么的?
  • Build.VERSION_CODES.M 是指 API 23 (Android Marshmallow)
  • 我将所有需要版本检查的方法保存在一个单独的类 (SDKHelper) 中,以便将来需求发生变化并且应用程序代码不会被检查乱七八糟通过所有不同的课程。
  • 你能给我举个例子吗?

标签: java android deprecated deprecation-warning


【解决方案1】:

据我从显示的部分中可以看出,您的执行方式是一种很好的做法。

但是,正如我目前所看到的,最佳实践是对您打算发布的每个类进行不同的细分,并在安装过程中堆叠程序。

这基本上意味着if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 排在班级的首位。

如果您的项目打算使用更多版本,我建议这样做:

public class Example extends moreExamples implements additionalExamples{
   switch(Build.VERSION.SDK_INT){
      case Build.VERSION_CODES.M:
         codeVersionM();
         break;
      case Build.VERSION_CODES.L:
         codeVersionL();
         break;
      case Build.VERSION_CODES.K:
         codeVersionK();
         break;
      default:
         errorNoBuildImplemented();
   }
}

【讨论】:

    【解决方案2】:

    最好使用 new 方法名。这样,当您将 min sdk 版本提高到 23 时,您最终可以摆脱兼容性类,而无需更改导入以外的任何代码。

    @SuppressWarnings("deprecation")
    public class TimePicker extends android.widget.TimePicker
    {
        public TimePicker(Context context)
        {
            super(context);
        }
    
        public TimePicker(Context context, AttributeSet attrs)
        {
            super(context, attrs);
        }
    
        public TimePicker(Context context, AttributeSet attrs, int defStyleAttr)
        {
            super(context, attrs, defStyleAttr);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
        {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        public void setHour(int hour)
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                super.setHour(hour);
            else
                super.setCurrentHour(hour);
        }
    
        public void setMinute(int minute)
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                super.setMinute(minute);
            else
                super.setCurrentMinute(minute);
        }
    
        public int getHour()
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                return super.getHour();
            else
                return super.getCurrentHour();
        }
    
        public int getMinute()
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                return super.getMinute();
            else
                return super.getCurrentMinute();
        }
    }
    

    【讨论】:

      【解决方案3】:

      你所做的没问题,但可能不是最好的解决方案,因为:

      • 您使用的是旧方法名而不是新方法名
      • 创建自定义类会强制您在布局和代码中使用该自定义类来替换框架的类。如果可以,最好避免创建自定义视图。

      一般有2种推荐方式:

      1) 继续使用已弃用的方法,直到您升级 minSDK。它将在新实现内部调用新方法:

      @Deprecated
      public void setCurrentHour(@NonNull Integer currentHour) {
          setHour(currentHour);
      }
      

      2) 创建一个静态帮助类,它将根据 SDK 版本调用正确的方法。这就是支持库已经为许多类所做的事情(TextViewCompatViewCompat,...):

      public class TimePickerCompat {
      
          public static void setHour(TimePicker timePicker, int hour) {
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                  timePicker.setHour(hour);
              } else {
                  timePicker.setCurrentHour(hour);
              }
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-14
        • 2021-02-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多