安卓视图动画-大屏幕上性能差

4
我开发了一个拼图游戏。在我的游戏中,我有几个自定义视图,这些视图嵌套在FrameLayout中,就像图层一样。每个视图显示一个位图。最大的位图是游戏板,它占据了大约2/3的屏幕大小。FrameLayout下还有背景图像。
当用户触摸屏幕时,会对这个游戏板视图执行简单的视图动画-它可以旋转或翻转。
这在小屏幕上都很好用,但用户报告说在Galaxy Tab上存在性能问题-在动画开始之前有明显的延迟,并且动画本身不太流畅。(这些屏幕上的游戏板位图大小约为600 * 600px)
以下是我的布局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootFrame"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/backgroundImageLayer"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/background"
        android:scaleType="fitXY"/>

    <FrameLayout android:id="@+id/gameFrame"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

            <com.mygame.BoardView
            android:id="@+id/boardLayer"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>

            <com.mygame.SomeObjectView
            android:id="@+id/someObjectLayer"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>

            <com.mygame.SomeOtherObjectView
            android:id="@+id/someOtherObjectLayer"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>

        </FrameLayout>    

</FrameLayout>

以下是我的 BoardView 类。

public class BoardView extends View {

Bitmap b;
int x;
int y;

public BoardView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // calculate size of the bitmap
    b = Bitmap.createBitmap(sizeX, sizeY, Bitmap.Config.ARGB_4444);
    createMyBitmap();
}

private void createMyBitmap() {
    Canvas c;
    c = new Canvas(b);
    // lots of c.drawRect() and c.drawLine() , using opaque and semi-transparent colors
}

@Override
public void onDraw(Canvas canvas) {
    canvas.drawBitmap(b, x, y, null);
}
}

以下是我进行动画的代码片段,非常简单:

AnimationRotate anim1=new AnimationRotate(startAngle,endAngle,centerX,centerY);
anim1.setDuration(500);
anim1.setInterpolator(newDecelerateInterpolator());
startAnimation(anim1);

那么是什么导致视图动画的延迟,我该如何解决它呢?我的方法正确吗?还是我应该使用SurfaceView或帧动画或其他东西?

你的根框架布局,需要使用框架还是可以使用相对布局?我现在正在移动中,所以无法访问帖子,但有一个关于布局使用的帖子,总结了使用相对布局或线性布局可以获得更好的性能。我已经采用了这种方法,看起来效果不错。 - Graham Smith
我会尝试使用相对布局而不是帧布局,看看是否有所帮助。谢谢。 - dop2000
4个回答

11

如果您还没有开启硬件加速,请开启。在3.0+中,布局渲染系统已经修改,通过将大部分软件渲染转移到硬件中,提高了这些大屏幕的性能。您可以在此处了解更多信息。

有一些东西在使用硬件加速时不起作用,但从您展示的内容看来应该没问题。最简单的方法是将以下内容添加到应用程序清单中,并针对3.0或更高版本进行编译(仍然可以支持较低的API级别)。

<application android:hardwareAccelerated="true"
...
>

所以我对清单文件进行了以下修改: <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="11"/> <application android:hardwareAccelerated="true" ....但是它显示出错信息“找不到属性hardwareAccelerated的资源标识符”。这是否意味着我必须将项目的API级别更改为11?那么之后应用程序是否能在v 2.1上运行? - dop2000
是的,您必须将其更改为API 11。只要不调用2.1中不存在的任何类/方法,它仍将运行。 XML属性不同,如果较低的API级别发现未知属性,则只会忽略它们(不会崩溃)。 Android开发博客上有很多与向后兼容性相关的内容,这里是SO上的另一个答案https://dev59.com/lVnUa4cB1Zd3GeqPd8kl#6891250 - smith324
我尝试添加hardwareAccelerated =“true”,但它会导致在Android 3.0及更高版本的设备上崩溃。它在以下行抛出NullPointerException:canvas.setMatrix(null); 因此,我不得不恢复我的旧清单文件.. - dop2000
好的,要么你的画布是null,要么它不想要一个null矩阵。我建议你进一步追踪这个问题。如果需要更多调试,请开一个新问题,但是尝试检查是否为null并使用单位矩阵(又称new Matrix())。 - smith324
“setMatrix”的描述表示如果矩阵为空,则将其设置为标识。代码在3.0模拟器上可以运行,但在真实的3.0设备上会崩溃。不幸的是,我只有一部2.2手机,无法在真实用户上进行实验,所以我唯一的选择是删除此参数。 - dop2000
这对我来说绝对是正确的答案,因为我遇到了非常类似的问题。是的,你可以像被接受的答案建议的那样完全重写代码,但通常这不是一个选项。 - Josh

3
我了解到设置以下属性可以提高性能:

我读过,设置以下属性可以帮助提高性能:

this.setAnimationCacheEnabled(true);
this.setDrawingCacheEnabled(true);

1
据我所知,所有的2D图形命令都非常缓慢,并且随着屏幕变大而变得越来越慢。我建议设置一个3D Surfaceview,将您的图像作为纹理放在四边形上进行渲染。这比使用2D图形要快得多。

0

你可以从这里阅读

View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        view.setLayerType(View.LAYER_TYPE_NONE, null);
    }
});
animator.start();

我认为这是不真实的。请查看文档中的注释。http://developer.android.com/guide/topics/graphics/hardware-accel.html注意:目前无法在视图层次结构中启用硬件加速。视图层次结构除了禁用硬件加速之外还有其他功能。有关它们的使用信息,请参见视图层。 - TWilly
文档的那一部分可能已经过时或者写得不太清楚。我已经在视图上切换了硬件层,并且明显可以看到行为和渲染方面的差异。 - Learn OpenGL ES

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