Android如何从Lollipop RippleDrawable中引用较新的Class?

4
我有一个在代码中创建涟漪可绘制对象的方法。
    public class StateApplier {    

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
        private static void add_Ripple(Resources res, StateListDrawable states
                , int color, int pressedColor){
            Drawable rd = new android.graphics.drawable.RippleDrawable(get_Ripple_ColorSelector(pressedColor)
                    , new ColorDrawable(color), null);
            states.addState(new int[] {}, rd);

        }

这段代码在Lollipop系统上运行良好,但是在KitKat系统上则崩溃了。以下是错误日志:

03-12 21:36:47.734: E/dalvikvm(26295): Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method com.acme.applib.Render.StateApplier.add_Ripple
03-12 21:36:47.734: W/dalvikvm(26295): VFY: unable to resolve new-instance 149 (Landroid/graphics/drawable/RippleDrawable;) in Lcom/acme/applib/Render/StateApplier;
03-12 21:36:47.734: D/dalvikvm(26295): VFY: replacing opcode 0x22 at 0x0000
03-12 21:36:47.738: W/dalvikvm(26295): VFY: unable to find class referenced in signature (Landroid/graphics/drawable/RippleDrawable;)
03-12 21:36:47.738: W/dalvikvm(26295): VFY: returning Ljava/lang/Object; (cl=0x0), declared Landroid/graphics/drawable/Drawable; (cl=0x0)
03-12 21:36:47.738: W/dalvikvm(26295): VFY:  rejecting opcode 0x11 at 0x0004
03-12 21:36:47.738: W/dalvikvm(26295): VFY:  rejected Lcom/acme/applib/Render/StateApplier;.create_Ripple (Landroid/content/res/Resources;II)Landroid/graphics/drawable/Drawable;
03-12 21:36:47.738: W/dalvikvm(26295): Verifier rejected class Lcom/acme/applib/Render/StateApplier;

我认为使用 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 应该能够让代码在低于Lollipop版本的设备上跳过。但是奇怪的是,在一个根本没有调用add_Ripple()方法但调用StateApplier类中另一个方法的活动中,它仍然会崩溃。

请注意,在调用该方法之前我还使用了API检查。

if( Build.VERSION.SDK_INT >=  Build.VERSION_CODES.LOLLIPOP){
add_Ripple(res, states, color, pressedColor);

在较老的设备上不会崩溃的情况下,引用新版API中的类的适当方法是什么。


1
我原以为使用 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 会在低于 Lollipop 版本的设备上跳过代码。但实际上,你需要添加代码来跳过它,例如 if (Build.VERSION.SDK_INT >= 21) { ... } - alanv
这是一个关于是否运行代码的条件语句,我已经在使用了。但是 @TargetApi(Build.VERSION...) 应该可以防止编译错误,让编译器在编译时跳过这些代码段。 - pt123
不,那个注解完全没有那么多的作用。它只是告诉代码检查工具在标记的方法中不应该警告 API 级别问题。请参考 TargetApi 的 javadocs。 - alanv
你找到解决方法了吗?我也遇到了同样的问题。 - Robby Smet
我已经在下面发布了我使用的解决方案作为答案。 - pt123
1个回答

3

我所做的是创建另一个名为StateApplierLollipop的类,并将所有与RippleDrawable相关的代码移动到该类中,而StateApplier中的代码仅会在Lollipop+设备上调用StateApplierLollipop中的代码。这样就可以避免在KitKat上崩溃了。

public class StateApplierLollipop {  
public static void add_Ripple(Resources res, StateListDrawable states
                , int color, int pressedColor){
    ...........
   }
}

public class StateApplier{
public static void add_Ripple(Resources res, StateListDrawable states
                    , int color, int pressedColor){
if( Build.VERSION.SDK_INT >=  Build.VERSION_CODES.LOLLIPOP){
   StateApplierLollipop.add_Ripple(....

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接