简体   繁体   English

动画不稳定,不经常更新

[英]Animation is choppy and isn't updated as often as it should

I am trying to complete simple animation of polyline shrinking. 我正在尝试完成折线收缩的简单动画。 I am accessing accelerometer X value, adding it to an array/list of points, and then updating the x coordinate of all those points. 我正在访问加速度计X值,将其添加到数组/点列表,然后更新所有这些点的x坐标。 Here's a drawing: 这是一张图:

在此输入图像描述

so let's say for example that my SCREEN_WIDTH is 800 px. 所以让我们假设我的SCREEN_WIDTH为800像素。

step 1: I add new point A = (0, 9.43634), nothing is drawn because I need at least 2 points 步骤1:我添加新点A =(0,9.43634),没有绘制任何内容,因为我需要至少2个点

points[(0, 9.43634)];

step 2: I add another point B = (0, 7.23134). 第2步:我添加另一个点B =(0,7.23134)。 I recalculate new X values, then I draw polyline using those points: 我重新计算新的X值,然后使用这些点绘制折线:

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

step 3: I add yet another point C = (0, 8.251251). 第3步:我添加另一个点C =(0,8.251251)。 I recalculate X values, then I draw polyline using those points: 我重新计算X值,然后使用这些点绘制折线:

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

step 4: ... 第4步: ......

My problem is that animation isn't fluid. 我的问题是动画不流畅。 When I set max number of points to be added to ~100 it seems to skip frames. 当我将要添加的最大点数设置为~100时,它似乎跳过帧。 It looks like if animation wasn't refreshed after adding a single points but rather after adding a couple of them. 看起来如果在添加单个点之后动画没有刷新,而是在添加了几个之后。

I've tried using arrays instead of ArrayList to avoid garbage collection, I've tried limiting animation speed etc. but nothing works. 我已经尝试使用数组而不是ArrayList来避免垃圾收集,我试过限制动画速度等但没有任何作用。

Is calculating new x values and drawing a polyline using 100+ points that slow? 是计算新的x值并使用100+点减慢折线? I also tried drawing lines between adjacent points but performance was the same. 我也试过在相邻点之间画线,但性能是一样的。

I am testing on Samsung Galaxy S2 if it's important. 我正在测试三星Galaxy S2,如果它很重要的话。

Too bad I can't post an animation of what it looks like here, but here is all necesarry code: 太糟糕了我不能发布这里看起来像什么的动画,但这里是所有necesarry代码:

Accelerometer_Test.java from accelerometer-test project: 来自加速计测试项目的Accelerometer_Test.java:

I've pasted it here because it is too long in my opinion 我在这里贴了它,因为我觉得它太长了

AndroidManifest.xml: 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>

MainActivity.java from accelerometer-test-android project: 来自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);
    }
}

My question is: how can I speed the animation up and make it more fluid? 我的问题是:如何加快动画速度并使其更流畅? I want it to update fast (each ~20[ms] would be perfect) and after every point added to pointsX . 我希望它快速更新(每个~20 [ms]将是完美的)并且在每个点添加到pointsX Am I doing something extremely stupid here? 我在这里做了一件非常愚蠢的事吗? I see in my logcat GC_CONCURRENT FREED repeatedly even though new points aren't being added after reaching MAX_NUM_POINTS limit. 我在logcat GC_CONCURRENT FREED反复看到,即使在达到MAX_NUM_POINTS限制后没有添加新点。 Finally, if recalculating new x values is in fact that bad for performance are there any algorithms to recalculate it faster? 最后,如果重新计算新的x值实际上对性能有害,那么是否有任何算法可以更快地重新计算它?

Use a profiler or instrument your code to see where the time is going. 使用分析器或仪器代码来查看时间的来源。 The Android DDMS tools are pretty good for tracking allocations down. Android DDMS工具非常适合跟踪分配。

Hiccups in rendering are often caused by garbage collections, caused by allocating "too much" (ie, most anything) in the render loop, so that's where I would start. 渲染中的打嗝通常是由垃圾收集引起的,这是由于在渲染循环中分配“太多”(即大多数东西)引起的,所以这就是我要开始的地方。 But you should find and follow actual hard data when trying to optimize your code. 但是,在尝试优化代码时,您应该找到并遵循实际的硬数据。 If it is allocation related, try pre-allocating all your "point" Vector2 objects in create . 如果它与分配相关,请尝试在create预先分配所有“point” Vector2对象。

I solved my problem. 我解决了我的问题。 There were three things that I did wrong: 我做错了三件事:

1) I was drawing, then updating, which is a reversed order of what I should do. 1)我正在绘画,然后更新,这是我应该做的相反的顺序。

2) I was allocating new objects inside render() method drawing Garbage Collector crazy: 2)我在render()方法中分配新对象绘制垃圾收集器疯狂:

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

3) I was using integer step instead of float step and that's why animation wasn't fluid: 3)我使用整数步而不是浮动步,这就是为什么动画不流畅的原因:

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

Try using a thread pool of at least two or three threads, that way you're not tying up your UI thread and work can be offloaded to other cores. 尝试使用至少两个或三个线程的线程池,这样你就不会占用你的UI线程,工作可以卸载到其他核心。 A handler on the UI thread can then be used to receive messages that have the X, Y and a timestamp so that the UI can be kept up to date. 然后,可以使用UI线程上的handler来接收具有X,Y和时间戳的消息,以便UI可以保持最新。

A setup like the ThreadPool class example shows would work well for this. 类似于ThreadPool类示例的设置可以很好地解决这个问题。 Along with the thread pool it also shows how you can reuse the same variables to prevent the unnecessary memory allocations and garbage collection. 它与线程池一起还显示了如何重用相同的变量来防止不必要的内存分配和垃圾回收。 Those can be expensive operations and every time the GC runs it's going to take +20ms itself before your app even gets a chance to start updating. 那些可能是昂贵的操作,并且每次GC运行时,在您的应用程序甚至有机会开始更新之前,它将花费+ 20ms。

Creating a Manager for Multiple Threads 为多个线程创建管理器

There is also a lot of talks from Google I/O about optimizing apps that is worth checking out. 谷歌I / O还有很多关于优化应用程序的讨论,值得一试。

Google I/O 2009 - Writing Real-Time Games for Android Google I/O 2011 - Accelerated Android Rendering Google I / O 2009 - 为Android版 Google I / O 2011 编写实时游戏 - 加速Android渲染

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM