Android测量每秒帧数Frames Per Second (FPS)的方法
本文实例讲述了Android测量每秒帧数FramesPerSecond(FPS)的方法。分享给大家供大家参考。具体如下:
MainThread.java:
packagenet.obviam.droidz; importjava.text.DecimalFormat; importandroid.graphics.Canvas; importandroid.util.Log; importandroid.view.SurfaceHolder; /** *@authorimpaler * *TheMainthreadwhichcontainsthegameloop.Thethreadmusthaveaccessto *thesurfaceviewandholdertotriggereventseverygametick. */ publicclassMainThreadextendsThread{ privatestaticfinalStringTAG=MainThread.class.getSimpleName(); //desiredfps privatefinalstaticintMAX_FPS=50; //maximumnumberofframestobeskipped privatefinalstaticintMAX_FRAME_SKIPS=5; //theframeperiod privatefinalstaticintFRAME_PERIOD=1000/MAX_FPS; //Stuffforstats*/ privateDecimalFormatdf=newDecimalFormat("0.##");//2dp //we'llbereadingthestatseverysecond privatefinalstaticintSTAT_INTERVAL=1000;//ms //theaveragewillbecalculatedbystoring //thelastnFPSs privatefinalstaticintFPS_HISTORY_NR=10; //lasttimethestatuswasstored privatelonglastStatusStore=0; //thestatustimecounter privatelongstatusIntervalTimer=0l; //numberofframesskippedsincethegamestarted privatelongtotalFramesSkipped=0l; //numberofframesskippedinastorecycle(1sec) privatelongframesSkippedPerStatCycle=0l; //numberofrenderedframesinaninterval privateintframeCountPerStatCycle=0; privatelongtotalFrameCount=0l; //thelastFPSvalues privatedoublefpsStore[]; //thenumberoftimesthestathasbeenread privatelongstatsCount=0; //theaverageFPSsincethegamestarted privatedoubleaverageFps=0.0; //Surfaceholderthatcanaccessthephysicalsurface privateSurfaceHoldersurfaceHolder; //Theactualviewthathandlesinputs //anddrawstothesurface privateMainGamePanelgamePanel; //flagtoholdgamestate privatebooleanrunning; publicvoidsetRunning(booleanrunning){ this.running=running; } publicMainThread(SurfaceHoldersurfaceHolder,MainGamePanelgamePanel){ super(); this.surfaceHolder=surfaceHolder; this.gamePanel=gamePanel; } @Override publicvoidrun(){ Canvascanvas; Log.d(TAG,"Startinggameloop"); //initialisetimingelementsforstatgathering initTimingElements(); longbeginTime;//thetimewhenthecyclebegun longtimeDiff;//thetimeittookforthecycletoexecute intsleepTime;//mstosleep(<0ifwe'rebehind) intframesSkipped;//numberofframesbeingskipped sleepTime=0; while(running){ canvas=null; //trylockingthecanvasforexclusivepixelediting //inthesurface try{ canvas=this.surfaceHolder.lockCanvas(); synchronized(surfaceHolder){ beginTime=System.currentTimeMillis(); framesSkipped=0;//resettingtheframesskipped //updategamestate this.gamePanel.update(); //renderstatetothescreen //drawsthecanvasonthepanel this.gamePanel.render(canvas); //calculatehowlongdidthecycletake timeDiff=System.currentTimeMillis()-beginTime; //calculatesleeptime sleepTime=(int)(FRAME_PERIOD-timeDiff); if(sleepTime>0){ //ifsleepTime>0we'reOK try{ //sendthethreadtosleepforashortperiod //veryusefulforbatterysaving Thread.sleep(sleepTime); }catch(InterruptedExceptione){} } while(sleepTime<0&&framesSkipped<MAX_FRAME_SKIPS){ //weneedtocatchup this.gamePanel.update();//updatewithoutrendering sleepTime+=FRAME_PERIOD;//addframeperiodtocheckifinnextframe framesSkipped++; } if(framesSkipped>0){ Log.d(TAG,"Skipped:"+framesSkipped); } //forstatistics framesSkippedPerStatCycle+=framesSkipped; //callingtheroutinetostorethegatheredstatistics storeStats(); } }finally{ //incaseofanexceptionthesurfaceisnotleftin //aninconsistentstate if(canvas!=null){ surfaceHolder.unlockCanvasAndPost(canvas); } }//endfinally } } /** *Thestatistics-itiscalledeverycycle,itchecksiftimesincelast *storeisgreaterthanthestatisticsgatheringperiod(1sec)andifso *itcalculatestheFPSforthelastperiodandstoresit. * *Ittracksthenumberofframesperperiod.Thenumberofframessince *thestartoftheperiodaresummedupandthecalculationtakespart *onlyifthenextperiodandtheframecountisresetto0. */ privatevoidstoreStats(){ frameCountPerStatCycle++; totalFrameCount++; //checktheactualtime statusIntervalTimer+=(System.currentTimeMillis()-statusIntervalTimer); if(statusIntervalTimer>=lastStatusStore+STAT_INTERVAL){ //calculatetheactualframespersstatuscheckinterval doubleactualFps=(double)(frameCountPerStatCycle/(STAT_INTERVAL/1000)); //storesthelatestfpsinthearray fpsStore[(int)statsCount%FPS_HISTORY_NR]=actualFps; //increasethenumberoftimesstatisticswascalculated statsCount++; doubletotalFps=0.0; //sumupthestoredfpsvalues for(inti=0;i<FPS_HISTORY_NR;i++){ totalFps+=fpsStore[i]; } //obtaintheaverage if(statsCount<FPS_HISTORY_NR){ //incaseofthefirst10triggers averageFps=totalFps/statsCount; }else{ averageFps=totalFps/FPS_HISTORY_NR; } //savingthenumberoftotalframesskipped totalFramesSkipped+=framesSkippedPerStatCycle; //resettingthecountersafterastatusrecord(1sec) framesSkippedPerStatCycle=0; statusIntervalTimer=0; frameCountPerStatCycle=0; statusIntervalTimer=System.currentTimeMillis(); lastStatusStore=statusIntervalTimer; //Log.d(TAG,"AverageFPS:"+df.format(averageFps)); gamePanel.setAvgFps("FPS:"+df.format(averageFps)); } } privatevoidinitTimingElements(){ //initialisetimingelements fpsStore=newdouble[FPS_HISTORY_NR]; for(inti=0;i<FPS_HISTORY_NR;i++){ fpsStore[i]=0.0; } Log.d(TAG+".initTimingElements()","Timingelementsforstatsinitialised"); } }
希望本文所述对大家的java程序设计有所帮助。