Imagine score counter made with Text() entity. Simple.
After I start a game, calling setText() causes launching a GC_EXPLICIT that slows down a game causing freezes, and after a few calls - problem disappears. Firstly I thought it's a problem with Strings and concatenation in Java, so I used a StringBuilder. The problem still exists. If I change setText("$" + score + "M") to simple setText("0") no hiccups are noticed!
The problem is in Font. Creation of Texture doesn't actually load characters to this Texture! All you need to do is after creating Font simply call:
pFont.prepareLetters("0123456789".toCharArray());
with all chars you need.
Occasional hiccups that were caused by GC_EXPLICIT were happening because Font in update() was explicitly calling System.gc(). Removing this line we were back on track below the green line, yeah! 60fps.
However, the author of AndEngine might had reasons for this explicit call. Since the stages are short we granted our app call this gc() when the GameScene is paused, quit or stage complete, anywhere where there is no excessive animation.
Preparing characters upfront did not sooth the hiccups, because the texts were dynamic and we could not prepare all possible characters to keep the System.gc() in this method, but honor it later.
Indeed preparing the letters upfront does not trigger GC_EXPLICIT, as it is described in the answer provided by the OP.
EDIT:
After some research, another thing that caused < 60fps, was the SoundPool, we should have playing a sound with volume 0f,0f and looping, in order to prevent the SoundPool reset to idle state and rearm again.
Related
I am trying to incorporate Android GraphView project into my app and all the time I have some strange problem with it.
My app requires drawing graph from real time data. I have thread with all the communication that is providing the data. In main thread I am reading this data and simply use mSeries1.appendData(new DataPoint(counter,data[0]),true,100); where counter is int that is incremented after each update.
Unfortunately at some point it freeze. I've tried putting it in synchronized block or changing the line of code to mSeries1.appendData(new DataPoint(counter,counter),true,100); and still this same result.
This is how the memory looks like during app running and when it freezes:
Does anyone have any idea what might be wrong in here?
EDIT:
This is my current method for updating my graph view:
public void onEventMainThread(ReadingsUpdateData data) {
mSeries1.appendData(new DataPoint(counter,data.getData()[0]),true,100);
counter++;
}
Maybe it's too late, but I had the similar problem and finally I found that when GraphView is appended a new data of "NaN" freezes.
So check the situation in which the result will be NaN such as divide by zero or something like that.
Although you do not specify the rate at which you add points, and how long for the app runs without crashing, you should expect things to go wrong at some point (you're potentially generating an infinite number of point objects, while the memory is indeed limited).
Do you need to have all the points the app has received from the beginning drawn ? If not, you could implement a sort of circular buffer that only keeps the X last values generated by your "provider thread", and update the graph each time you receive a new value with the method
your_series.resetData( dataPoint[] my_circular_buffer_of_data_points );
This thread is quite similar to your problem, have a look at it !
I am currently writing an app that should display a real time measurement curve in a scrolling fashion (think ECG recorder or oscilloscope). An unexpected system call in the UI-Thread makes the display stutter.
The data rolls in via bluetooth. All works fine and the display is reasonably smoothly scrolling with an average update rate of 26 frames/s. But, nevertheless the display is stuttering remarkably.
I used traceview to get more insight and according to traceview the stuttering is the result of a call to android/view/ViewRoot.handleMessage which lasts 131 ms per call on average.
If I dig down further in traceview the cycles are burnt inside android/view/ViewRoot.performTraversals. 92% of these CPU cycles are consumed in mostly recursive calls to android/view/View.measure.
From there it gets complicated due to the recursive call structure. But I can find calls to the onMeasure() method of LinearLayout, FrameLayout and RelativeLayout. The onMeasure() method of each Layout type consumes about the same amount of CPU cycles. Which is very strange since in my activity I use only a simple LinearLayout with just 2 Elements.
I just see no reason on why a supposed re-layout of a LinearLayout with 2 Elements performs calls to non-used Layouts and takes a whopping 131 ms to do that.
Further info:
Platform HTC desire HD with Android 2.3.1.
I use a handler to perform the drawing in the UI thread.
The Layout is a simple LinearLayout with 2 Elements: a custom view and a textField.
The status bar is hidden with getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);.
The drawing is performed on each new block of data, which arrives approx. every 50 ms.
The drawing itself uses a canvas and is performant enough to keep up with the incoming data.
After that long explanation, here are the questions:
What is calling the android/view/ViewRoot.handleMessage? (the calls are relatively equal spaced every 850 ms and have no obvious link (no direct calls, number of calls and relative positions are not linked to the message handler for drawing) to any activity of my Activity)
How can I suppress the calls to android/view/ViewRoot.handleMessage or how can I make them faster (there are just 2 elements in my LinearLayout)
the calls to unused layouts first got me think of the status bar or some hidden activity (e.g. home screen), which may use such layouts. But how come those calls are part of the trace of my activity? As far as I understand the trace should only trace the active process. e.g. the calls of my service which produces the real time data is not part of the trace.
Is there any possibility to trace individual calls to some system components? When I zoom in in traceview I see this call sequence: toplevel -> android/os/Message.clearForRecycle() -> android/os/MessageQueue.nativePollOnce() -> android/os/SystemClock.uptimeMillis() -> com/htc/profileflag/ProfileConfig.getProfilePerformance() -> android/os/Handler.dispatchMessage() -> android/view/ViewRoot.performTraversals()
Off topic: Is there a possibility to export the data which is shown inside traceview (parents-children-CPU time etc.) other than a screenshot?
Ok, I found the reason for the long call to android/view/ViewRoot.handleMessage.
This was indeed caused by my application.
My App has 2 screens (Activities) one with a complicated Layout for status information and the other one the real time display of incoming data.
The data, which comes in over bluetooth contains mixed real time data and status data. When I switch to the real time Activity, I was stopping the status Activity with finish(); after starting the new real time Activity. Unfortunately this is not enough to stop also the message handler, which receives the new status information in the UI thread, and continued to update status data in an invisible and finished Activity. The relayout of this activity caused the stutter of the real time data.
This is now solved. The display scrolling is now reasonable smooth.
Thanks for your patience. May it be useful to anyone who stumbles on this Thread on stackoverflow.
jepo
I would assume that someone would have found an easy solution to this but I haven't found a straight-forward method. I want to build a seeker bar for playing back audio through the MediaPlayer. I haven't been able to find something like an onSeekChanged listener in the MediaPlayer object so I've built an AsyncTask that just keeps refreshing through a while(playing) loop and updates the duration and bar. This doesn't seem to be the best way, however, since this while loop causes the app to run very slowly (the audio doesn't lag, but buttons like pause are delayed). So I want to know what the best implementation is for building a seeker that is efficient. This isn't a difficult question since so many apps use it, I just want to know what the proper way of doing this should be. Thanks!
First of all you need put sleep at least 1 millisecond in your cycle whit:
Thread.sleep(1);
Second you can calculate needed time for next recheck:
Thread.sleep(1000 - currentPos % 1000);
This algorithm is used in standard MediaController.
I'm creating a spades app with 1 human player and 3 computer players.
The problem that I am having is, the play must happen sequentially (clockwise) and I need my program to wait on the player input. I can't use wait() and notify(). I have tried while loops to check whether the user has selected a card but those stop the program from running. I've tried recursive methods that won't return anything until the player has chosen a card. That too does not work. So what do I do? I'm stuck.
My method goes like this (leaving out the non-pertinent code)
private void game(){
while(there are more tricks to be played)
while(each player has not played){
if(human turn)
get input from player
else
computer plays
}
}
Maybe you should change a little bit your game controller. Instead of waiting for anything, have your program continuously paint the screen. If user inputs nothing, same screen is paint all the time.
Once he presses a key (or clicks a card or whatever events you have), simply modify the paint method's argument (the screen to be painted). Thus you will separate painting the screen and input handling. It's a common technique called MVC model.
Maybe this will help (it's my game creating blog, and the links inside it are also helpful):
http://m3ph1st0s.blogspot.ro/2012/12/create-games-with-libgdx-library-in.html
You don't need to adapt all your game to the game described there, only the technique of separating input from painting. As a general technique, you should NOT have input determine painting.
Hope it helps. Don't hesitate to request further help.
You can try to add Event Handlers. It will try triger a event every time the user selects a card.
Try this.
Create one thread and in that threat call sleep(1000);
I am facing the problem of low memory. Low memory:no more background process And here is the scenario.
I am using a list which gets its data from a string array, it has a custom background, Clicking on item, the list gets another string array to display as second or third level. Information for three levels written in database.
After third level, there are two more levels for which data is going to be fetched from web services,
And that causes the low memory error.
How can I get rid of the solution?
Edit : After having some digging I found that the GC is trying to (kill or) restart in case of its already crashed com.android.inputmethod.latin/.latinIMEservice. One notable point is that the application is translated in french and italian, but this screen does not have any text for translation, does this information helps??
Edit 2: After a detailed study of traceview I found that all the text views have custom fonts applied in it. (There is a call of TypeFace.createFromAsset()) that IMO causes the crashes.
And the problem lies in the fact that I have to keep the fonts....
can It be possible to avoid crash and have the fonts?? (Because i think the answer is no: But still waiting for some opinions)
Edit 3 : After removing the custom fonts the performance of application is much better. Hence I can suspect the font is the only culprit here. And that's why I am editing question. The font I use is helvetica.
Can using external fonts cause application to crash or running out of memory? If yes can you describe the cause in more detail??
Thanks
If you are using code similar to:
Typeface font = Typeface.createFromAsset(getContext().getAssets(),
"fonts/Helvetica.ttf");
try making "font" a global variable so it only gets loaded once. Otherwise it can be loaded repeatedly, quickly consuming memory. See this message for a little more detail
Well, question is a bit unclear to have answered:
After each level - do you switch/start to another Activity? If so you shouldn't keep anywhere references to old activity. Otherwise it could trigger OOM problems
I suppose you're fetching data using some kind of Cursor alike object. Cursor's are very memory-consuming objects, so you'd better not only just close Cursor's, but you should also call Cursor.deactivate()