where to call invalidate() for animation purpose? - android

I am programming a simple game and has to draw animation on the screen and currently calling invalidate() method from within onDraw(). I simply wish to periodically update my canvas.
I would like to move the invalidate() call somewhere else as calling within onDraw() is rather bad. However, my target platform is android gingerbread and I probably can't utilize those methods which involve multithreading.
Is there anyway to setup a timer outside of onDraw() which invalidate() if the time lapse interval meets my desire without involving multithreading?

I probably can't utilize those methods which involve multithreading.
That's not true. It is not what you need though. If you need to call invalidate periodically on your view, you can use the View's internal handler and its postDelayed method, to invoke invalidate(). The runnable runs on the UI Thread.

Wouldn't it be an idea to call invalidate() after an user input?
If you want a timer look to this:
https://developer.android.com/training/scheduling/alarms.html
This method should be viable with your android version.

Related

Android: What's the difference between Activity.runOnUiThread and View.post?

What's the difference between Activity.runOnUiThread and View.post, could someone, please, explain?
There is no real difference, except that the View.post is helpful when you don't have a direct access to the activity.
In both cases, if not on UI thread, Handler#post(Runnable) will be called behind the scenes.
As CommonsWare mentioned in the comment, there is a difference between the two - when called on Ui thread, Activity#runOnUiThread will call the run method directly, while View#post will post the runnable on the queue (e.g. call the Handler#post)
The important point IMO is that both have the same goal, and for whoever use it, there should be no difference (and the implementation may change in the future).
Another difference between Activity.runOnUiThread and view.post() is that the runnable in view.post() is called after the view is attached to a window.
Either are acceptable for most situations and for the most part they are interchangeable, but they are subtly different. The biggest difference of course is that one is available from an Activity and the other from a View. There's a lot of overlap between those, but sometimes in an Activity you will not have access to a View, and sometimes in a View you will not have access to an Activity.
One of the edge cases I've encountered with View.post I mentioned in an answer to another SO question on View.post: View.post only works from another thread when the View is attached to a window. This is rarely a problem, but can occasionally cause the Runnable to never execute, especially if you call View.post in the onCreate method of your Activity. An alternative is to use Handler.post which is what Activity.runOnUiThread and View.post use under the covers anyway.
(edited for accuracy, added "from another thread")
Another difference: post is per View; runOnUiThread is per Activity.
This means it will be possible (in the future?) to do view.getQueue / activity.getQueue and get exactly what you want without your own tracking or filtering code.

Roboguice, AndroidAnnotations and events between threads

When RoboGuice fires Event, where will my event callback be executed, in which thread?
For example, I have an activity which has do(#Observes OnUpdateUiEvent e). I also have a background thread which fires new OnUpdateUiEvent("data"). So, my do() method will be executed in bg thread as I understood? What will be, if I annotate do() with #Background from AndroidAnnotations? Should preprocessor make call to do() in runInUiThread()?
If everything is right, I think this pattern will provide the easiest way of communicating between threads.
As far as I can see here and there, you can specify the way threads should mix with events in RoboGuice, by using #Observes(EventThread.CURRENT), #Observes(EventThread.UI) or #Observes(EventThread.BACKGROUND).
The default is "CURRENT", which means that if you didn't specify anything, the event listening method will be executed in the same thread as the method receiving the event.
So yes, if you fire your event from a background thread, do() will be executed in a background thread.
If you add #Background on the do() method, then it will always be executed in a separate thread, different from the one where you fired the event.
If you're not sure, put a breakpoint and watch the thread names :-) .
Did that answer your question?

Opengl-es calling onDrawFrame manually

I am creating a game loop and I need to be able to call onDrawFrame (from inside the renderer manually) in order to "skip frames" if I find that I am falling behind on processes.
Currently I have a GLSurfaceView class that calls
setRenderer(glSurfaceRenderer);
With this set up I understand that onDrawFrame is called every tick.
I tried putting the above call inside a method so that I could call it from inside my game loop but on the second run of the game loop I crash with the message saying
setRenderer has already been called for this instance
Is there a way to call the renderer manually every frame
Will just calling the
onDrawFrame
method work properly. Or is it not good practice to control the renderer in such a way when using openGL
I don't see how calling setRenderer() nor manually calling onDrawFrame() in the game loop will solve anything. You should refactor your rendering calls to take into account the time it takes draw so in other words time based animation. In any case manually calling onDrawFrame() without a call to eglMakeCurrent() before any drawing calls won't work as you have both the renderer and game loop thread drawing.
Edit: Since you are using GLSurfaceView, you can call requestRender() from your game loop to trigger a render if you feel RENDERMODE_CONTINUOUSLY is too slow for you.

invalidate() inside of a thread android app

I'm new to programming androids but I have quite a bit of experience programming blackberries.
I created an app that has an activity class (main.java) and a view class (game.java).
Inside the view class I have some bitmaps being drawn to the screen. I created a thread and I'm moving the images around in the thread. However when I call invalidate() inside the thread it never redraws the screen.
Are you not able to invalidate() the screen from a thread? I know the thread is running and the invalidate is being called, it just never makes the changes on the screen.
You have to use View.postInvalidate() if you call it from a non-UI thread.
According to docs:
public void postInvalidate ()
Since: API Level 1
Cause an invalidate to happen on a subsequent cycle through the event loop. Use this to invalidate the View from a non-UI thread.

Does a thread safe timer exist?

Is there another equivalent of Timer for android which is thread safe?
Using the timer causes problems in my application while updating the gui, most of the time it complains that gui is being updated from another thread, i tried using handlers but that didn't fix the problem.
Use postDelayed() on any of your Views. Have it do its work then call postDelayed() again.
Or, use runOnUiThread() instead of messing with your own Looper/Handler.
Or, create your Handler as a private data member of the class with an ordinary initializer -- it would appear you are trying to create it in the background thread, which will not work.

Categories

Resources