在android中处理已弃用的方法

时间:2015-10-14 09:53:56

标签: java android deprecated deprecation-warning


我目前正在构建一个针对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类的导入)。

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

由于

3 个答案:

答案 0 :(得分:4)

就我所能看到的部分而言,你所表现的方式是良好的做法。

但是,正如我到目前为止所看到的,最佳做法是从您要发布的每个类中进行不同的细分,并在安装过程中堆叠程序。

这基本上意味着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();
   }
}

答案 1 :(得分: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);
        }
    }

}

答案 2 :(得分:0)

最好使用 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();
    }
}