动画不稳定,不经常更新

时间:2013-09-23 08:41:00

标签: java android animation libgdx

我正在尝试完成折线收缩的简单动画。我正在访问加速度计X值,将其添加到数组/点列表,然后更新所有这些点的x坐标。这是一张图:

enter image description here

所以让我们假设我的SCREEN_WIDTH为800像素。

第1步:我添加新点A =(0,9.43634),没有绘制任何内容因为我需要至少2分

points[(0, 9.43634)];

第2步:我添加另一个点B =(0,7.23134)。我重新计算新的X值,然后使用这些点绘制折线:

points[(0, 9.43634), (800, 7.23134)];

第3步:我添加了另一个点C =(0,8.251251)。我重新计算X值,然后使用这些点绘制折线:

points[(0, 9.43634), (400, 7.23134), (800, 8.251251)];

第4步: ......

我的问题是动画不流畅。当我将要添加的最大点数设置为~100时,它似乎跳过帧。看起来如果在添加单个点之后动画没有刷新,而是在添加了几个之后。

我尝试使用数组而不是ArrayList来避免垃圾收集,我尝试限制动画速度等但没有任何效果。

计算新的x值并使用100多个缓慢的点绘制折线?我也尝试在相邻点之间画线,但性能是相同的。

我正在测试三星Galaxy S2,如果这很重要的话。

太糟糕了我无法发布这里的动画,但这里有所有必要的代码:

来自加速计测试项目的

Accelerometer_Test.java:

I've pasted it here because it is too long in my opinion

的AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gurniak.accelerometer.test"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="18" />

<uses-permission android:name="android.permission.WAKE_LOCK"/>

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:allowBackup="true" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:screenOrientation="landscape"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>
来自accelerometer-test-android项目的

MainActivity.java:

package com.gurniak.accelerometer.test;

import android.os.Bundle;

import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import android.util.Log;

public class MainActivity extends AndroidApplication {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
        cfg.useGL20 = true;
        cfg.useAccelerometer = true;
        cfg.useCompass = false;
        cfg.useWakelock = true;

        initialize(new Accelerometer_Test(), cfg);
    }
}

我的问题是:如何加快动画速度并使其更流畅?我希望它快速更新(每个~20 [ms]将是完美的)并且在每个点添加到pointsX之后。我在这里做了一件非常愚蠢的事吗?我在logcat GC_CONCURRENT FREED中反复看到,即使在达到MAX_NUM_POINTS限制后没有添加新点。最后,如果重新计算新的x值实际上对性能有害,那么是否有任何算法可以更快地重新计算它?

3 个答案:

答案 0 :(得分:1)

使用分析器或仪器代码来查看时间的来源。 Android DDMS tools非常适合跟踪分配。

渲染中的打嗝通常是由垃圾收集引起的,这是由于在渲染循环中分配“太多”(即大多数东西)引起的,所以这就是我要开始的地方。但是,在尝试优化代码时,您应该找到并遵循实际的硬数据。如果与分配相关,请尝试在Vector2中预先分配所有“点”create个对象。

答案 1 :(得分:1)

我解决了我的问题。我做错了三件事:

1)我正在绘画,然后更新,这是我应该做的相反顺序。

2)我在render()方法中分配新对象,绘制垃圾收集器疯狂:

points.add(new Vector2(0, newValue));

3)我使用整数步而不是浮动步,这就是为什么动画不流畅的原因:

int step = (int) Math.ceil(SCREEN_WIDTH / ((points.size - 1) * 1.0));

答案 2 :(得分:0)

尝试使用至少两个或三个线程的线程池,这样就不会占用UI线程,并且可以将工作卸载到其他核心。然后,可以使用UI线程上的handler来接收具有X,Y和时间戳的消息,以便UI可以保持最新。

ThreadPool类示例所示的设置可以很好地解决这个问题。它与线程池一起还显示了如何重用相同的变量来防止不必要的内存分配和垃圾回收。那些可能是昂贵的操作,每次GC运行时,在您的应用程序甚至有机会开始更新之前,它将花费+ 20ms。

Creating a Manager for Multiple Threads

Google I / O还有很多关于优化应用的讨论,值得一试。

Google I/O 2009 - Writing Real-Time Games for Android Google I/O 2011 - Accelerated Android Rendering