2013-09-23 4 views
0

Я пытаюсь выполнить простую анимацию сокращения полилинии. Я обращаюсь к значению акселерометра X, добавляя его к массиву/списку точек, а затем обновляя координату x всех этих точек. Вот рисунок:Анимация изменчивая и не обновляется так часто, как должно было

enter image description here

так скажем, например, что мой SCREEN_WIDTH 800 пикс.

шаг 1: добавить новую точку А = (0, 9,43634), ничего не рисуется, потому что нужно по крайней мере 2 очка

points[(0, 9.43634)]; 

шаг 2: добавить другую точку B = (0, 7,23134). Я пересчитать новые значения X, то я нарисовать ломаную линию, используя те пункты:

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

шаг 3: добавить еще одну точку С = (0, 8.251251). Я пересчитывать значения X, то я рисую ломаную линию, используя эти пункты:

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

шаг 4: ...

Моя проблема заключается в том, что анимация не жидкость. Когда я устанавливаю максимальное количество точек, добавляемых в ~ 100, кажется, что пропускают кадры. Похоже, если анимация не обновилась после добавления отдельных точек, а после добавления нескольких из них.

Я пытался использовать массивы вместо ArrayList, чтобы избежать сбора мусора, я пытался ограничить скорость анимации и т. Д., Но ничего не работает.

Рассчитывает новые значения x и рисует полилинию с использованием более 100 пунктов, что медленно? Я также пытался рисовать линии между соседними точками, но производительность была одинаковой.

Я тестирую Samsung Galaxy S2, если это важно.

Жаль, я не могу отправить анимацию, что она выглядит как здесь, но здесь все necesarry код:

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> 

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 [мс] был бы идеальным) и после каждой добавленной точки до pointsX. Я делаю здесь что-то очень глупо?Я вижу в своем logcat GC_CONCURRENT FREED неоднократно, даже если новые точки не добавляются после достижения предела MAX_NUM_POINTS. Наконец, если пересчет новых значений x на самом деле является плохим для производительности, есть ли алгоритмы для его пересчета быстрее?

ответ

1

Я решил свою проблему. Было три вещи, которые я сделал неправильно:

1) Я рисовал, а затем обновлял, что является обратным порядком того, что я должен делать.

2) Я выделение новых объектов внутри render() метода рисования сборщика мусора ума:

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

3) Я использую целочисленный шаг вместо шага поплавка, и именно поэтому анимация была не жидкость:

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

Попробуйте использовать пул потоков по меньшей мере из двух или трех потоков, таким образом, вы не связываете свой поток пользовательского интерфейса, и работа может быть выгружена на другие ядра. A handler в потоке пользовательского интерфейса затем можно использовать для приема сообщений, имеющих X, Y и временную метку, чтобы пользовательский интерфейс мог быть обновлен.

Установки, подобные показам классов классов ThreadPool, будут хорошо работать для этого. Наряду с пулом потоков он также показывает, как вы можете повторно использовать одни и те же переменные, чтобы предотвратить ненужные выделения памяти и сбор мусора. Это могут быть дорогостоящие операции, и каждый раз, когда GC запускается, он будет принимать + 20 мс, прежде чем ваше приложение даже получит шанс начать обновление.

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

1

Использование профайлера или инструмента код, чтобы увидеть, где будет время. Android DDMS tools довольно хороши для отслеживания распределения вниз.

Икоты в рендеринге часто вызваны сборками мусора, вызванными распределением «слишком много» (то есть всего всего) в цикле рендеринга, так что я начну. Но при попытке оптимизировать свой код вы должны найти и следовать фактическим жестким данным. Если это связано с распределением, попробуйте предварительно выделить все ваши «точки» Vector2 объектов в create.

Смежные вопросы