2013-09-23 40 views
0

我正試圖完成折線縮小的簡單動畫。我正在訪問加速度計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上進行測試,如果它很重要的話。

太糟糕了,我不能發表什麼它看起來像在這裏,但這裏是所有necesarry代碼動畫:

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

從加速度計的測試項目Accelerometer_Test.java

的AndroidManifest.xml:

從加速度計的測試,Android項目
<?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:

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之後。我在這裏做了一件非常愚蠢的事情嗎?即使在達到MAX_NUM_POINTS限制後沒有添加新點數,我在我的logcat GC_CONCURRENT FREED中也會看到。最後,如果重新計算新的x值實際上對性能不利,有沒有算法可以更快地重新計算它?

回答

1

我解決了我的問題。有三件事我做錯了:

1)我正在繪製,然後更新,這是我應該做的相反的順序。

2)I被分配內部render()方法繪製垃圾收集器的新對象瘋狂:

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

3)我用整數步驟代替浮動步驟,這就是爲什麼動畫不是流體:

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

嘗試使用至少兩個或三個線程的線程池,這樣您就不會捆綁您的UI線程,並且工作可以卸載到其他核心。 UI線程上的handler然後可以用於接收具有X,Y和時間戳的消息,以便UI可以保持最新。

ThreadPool類示例顯示的設置對此很有效。與線程池一起,它還顯示瞭如何重用相同的變量來防止不必要的內存分配和垃圾回收。這些可能是昂貴的操作,並且每次GC運行時,它都會在你的應用程序甚至有機會開始更新之前自行採用+ 20ms。

Creating a Manager for Multiple Threads

還有很多從谷歌I/O有關優化的應用程序,是值得一試的會談。

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

1

使用分析器或儀器代碼,看看那裏的時候是怎麼回事。 Android DDMS tools非常適合跟蹤分配。

渲染中的打嗝通常是由於渲染循環中分配「太多」(即大部分任何東西)導致的垃圾回收引起的,所以這就是我要開始的地方。但是當你嘗試優化代碼時,你應該找到並遵循實際的硬數據。如果分配相關,請嘗試預先分配create中的所有「點」Vector2對象。

相關問題