如何让我的动画更流畅的Andr​​oid [英] How do I make my animation smoother Android

查看:254
本文介绍了如何让我的动画更流畅的Andr​​oid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,具有在屏幕上运行的一球。当球是介于应用程序记录了一些声音,计算FFT和做一些额外的分析。

这是AsyncTask的处理,但是动画仍然简要口吃。

有没有人对如何使它运行顺畅什么建议?

感谢

低于code:

 进口com.ben.applicationLayer.GameView;
进口dataObjectLayer.Sprite;
进口dataObjectLayer.MusicalNote;
进口android.media.AudioRecord;
进口android.media.MediaRecorder.AudioSource;
进口android.media.AudioFormat;
进口android.os.AsyncTask;

公共类recorderThread扩展的AsyncTask<雪碧,太虚,整数GT; {

短[] audioData;
INT缓冲区大小;
雪碧ballComp;

@覆盖
保护整数doInBackground(雪碧......球){

    MusicalNote注=球[0] .expectedNote;
    ballComp =球[0];
        布尔记录= FALSE;
        双频率;
        INT采样率= 8192;
        AudioRecord记录= instatiateRecorder(采样率);
        双[]幅度=新的双[1024];
        双[] audioDataDoubles =新的双[2048];

        而(!记录){//循环,直到录制时

        如果(recorder.getState()== android.media.AudioRecord.STATE_INITIALIZED)
//检查是否记录已初始化呢。
        {
            如果(recorder.getRecordingState()== android.media.AudioRecord.RECORDSTATE_STOPPED)
                  recorder.startRecording();
//检查,看看是否记录已经停止或不记录,并使其记录。
            其他 {
               双MAX_INDEX;
               recorder.read(audioData,0,BUFFERSIZE);
//读取PCM音频数据到audioData阵列

               computeFFT(audioDataDoubles,幅度);

               MAX_INDEX = getLargestPeakIndex(幅度);

               频率= getFrequencyFromIndex(MAX_INDEX,采样率);

            //检查是否正确的频率,指定号码
               INT correctNo = correctNumber(频率,注意);

checkIfMultipleNotes(correctNo,MAX_INDEX,频率,采样率,幅度注);

               如果(audioDataIsNotEmpty())
                   记录= TRUE;
               如果(correctNo!= 1)
                   返回correctNo;
              }
        }
        其他
        {
            记录= FALSE;
            记录= instatiateRecorder(采样率);
        }
    }

        如果(recorder.getState()== android.media.AudioRecord.RECORDSTATE_RECORDING)
        {
            killRecorder(录像机);
        }

        返回1;
}


私人无效killRecorder(AudioRecord记录器){
    recorder.stop(); //结束线程之前停止记录
    recorder.release(); //释放录音机资源
    记录= NULL; //设置为垃圾回收记录
}

@覆盖
保护无效onPostExecute(整数结果){
    (结果== 2)
        GameView.score ++;
    }

私人AudioRecord instatiateRecorder(INT采样率){
        BUFFERSIZE = AudioRecord.getMinBufferSize(采样率,AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT)* 2;
 //获取与此录音所用的缓冲区大小

AudioRecord记录=新AudioRecord(AudioSource.MIC,采样率,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,缓冲区大小); //实例化AudioRecorder

    audioData =新的短[BUFFERSIZE] //短阵的PCM数据被放入。
        返回记录;
}

}
 

解决方案

使用的AsyncTask是沿着你想要做什么样的线路。但是,我建议使用一个线程池。然后,你可以把你的动画作为一个任务,添加您的录音作为一个任务时,FFT的另一项任务,和你额外的分析任务。

简要口吃可能分配资源用于记录在动画线程的结果。使用游泳池意味着您不必在创建运行您的音频任务线程暂停。显然,有些code将方便全面了解您的问题。

看看:

的ScheduledThreadPoolExecutor <一href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html" rel="nofollow">http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

的ThreadPoolExecutor 的http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

你可能想要做一个很简单的例子:

在你的活动,你可以定义这个启动的任务

 的ExecutorService线程池=新的ScheduledThreadPoolExecutor(2);
录音记录=新的记录();
球球=新球(线程池,记录);
threadPool.submit(球);
 

Ball.java

 进口java.util.concurrent.ExecutorService中;

公共类球实现Runnable {
    私人最终录音记录;
    私人最终的ExecutorService线程池;

    私人布尔条件;
    私人布尔活跃;

    公共球(ExecutorService的线程池,录音记录){
        this.record =记录;
        this.threadPool =线程池;
        this.active = TRUE;
    }

    @覆盖公共无效的run(){
        而(this.active){
            moveBall();
            如果(isBallHalfway()){
                threadPool.submit(记录);
            }
        }
    }

    私人布尔isBallHalfway(){
        返回的条件; //条件确定何时球中途
    }

    私人无效moveBall(){
        // code键移动球
    }
}
 

Recording.java

 公共类记录实现Runnable {
    @覆盖公共无效的run(){
        //完成录制任务在这里
    }
}
 

I have an app that has a ball running across the screen. When the ball is halfway the application records some audio, computes the FFT and does some extra analysis.

This is handled by Asynctask, however the animation still briefly stutters.

Does anyone have any suggestions on how to make it run smoother?

Thanks

code below:

import com.ben.applicationLayer.GameView;
import dataObjectLayer.Sprite;
import dataObjectLayer.MusicalNote;
import android.media.AudioRecord;
import android.media.MediaRecorder.AudioSource;
import android.media.AudioFormat; 
import android.os.AsyncTask;

public class recorderThread extends AsyncTask<Sprite, Void, Integer> {

short[] audioData;
int bufferSize;    
Sprite ballComp;

@Override
protected Integer doInBackground(Sprite... ball) {

    MusicalNote note = ball[0].expectedNote;
    ballComp = ball[0];
        boolean recorded = false; 
        double frequency;
        int sampleRate = 8192;  
        AudioRecord recorder = instatiateRecorder(sampleRate);
        double[] magnitude = new double[1024];
        double[] audioDataDoubles = new double[2048];

        while (!recorded) {  //loop until recording is running

        if (recorder.getState()==android.media.AudioRecord.STATE_INITIALIZED) 
// check to see if the recorder has initialized yet.
        {
            if (recorder.getRecordingState()==android.media.AudioRecord.RECORDSTATE_STOPPED)
                  recorder.startRecording();  
//check to see if the Recorder has stopped or is not recording, and make it record.                               
            else {             
               double max_index;
               recorder.read(audioData,0,bufferSize);   
//read the PCM audio data into the audioData array

               computeFFT(audioDataDoubles, magnitude);

               max_index = getLargestPeakIndex(magnitude);

               frequency = getFrequencyFromIndex(max_index, sampleRate);

            //checks if correct frequency, assigns number
               int correctNo = correctNumber(frequency, note);

checkIfMultipleNotes(correctNo, max_index, frequency, sampleRate, magnitude, note);

               if (audioDataIsNotEmpty())
                   recorded = true;
               if (correctNo!=1)
                   return correctNo;
              }
        }
        else
        {
            recorded = false;
            recorder = instatiateRecorder(sampleRate);
        }
    }

        if (recorder.getState()==android.media.AudioRecord.RECORDSTATE_RECORDING) 
        {
            killRecorder(recorder);
        }

        return 1;
}


private void killRecorder(AudioRecord recorder) {
    recorder.stop(); //stop the recorder before ending the thread
    recorder.release(); //release the recorders resources
    recorder=null; //set the recorder to be garbage collected
}

@Override
protected void onPostExecute(Integer result) {  
    (result == 2)
        GameView.score++;
    }

private AudioRecord instatiateRecorder(int sampleRate) {    
        bufferSize= AudioRecord.getMinBufferSize(sampleRate,AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT)*2;
 //get the buffer size to use with this audio record

AudioRecord recorder = new AudioRecord (AudioSource.MIC,sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,bufferSize); //instantiate the AudioRecorder

    audioData = new short [bufferSize]; //short array that pcm data is put into.         
        return recorder;
}

}

解决方案

Using an Asynctask is along the lines of what you want to do. However, I would suggest using a thread-pool. You can then put your animation in as a task, add your audio recording as a task, the FFT as another task, and your additional analysis as a task.

The brief stutter is likely the result of allocating resources for the recording in the animation thread. Using a pool means you won't have to pause while creating the thread to run your audio tasks. Obviously, some code would be handy to fully understand your problem.

Take a look at:

ScheduledThreadPoolExecutor http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

or

ThreadPoolExecutor http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

A very simple example of what you might want to do:

In your activity you can define this to start up the tasks

ExecutorService threadPool = new ScheduledThreadPoolExecutor(2);
Recording record = new Recording();
Ball ball = new Ball(threadPool, record);
threadPool.submit(ball);

Ball.java

import java.util.concurrent.ExecutorService;

public class Ball implements Runnable { 
    private final Recording record;
    private final ExecutorService threadPool;

    private boolean condition;  
    private boolean active;

    public Ball(ExecutorService threadPool, Recording record) {
        this.record = record;
        this.threadPool = threadPool;
        this.active = true;
    }

    @Override public void run() {
        while (this.active) {
            moveBall();
            if (isBallHalfway()) {
                threadPool.submit(record);
            }
        }
    }

    private boolean isBallHalfway() {
        return condition; // Condition for determining when ball is halfway
    }

    private void moveBall() {
        // Code to move the ball
    }
}

Recording.java

public class Recording implements Runnable {
    @Override public void run() {
        // Do recording tasks here
    }
}

这篇关于如何让我的动画更流畅的Andr​​oid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆