why the interval of invoking applyTransformation() is about 16ms? - android

recently, I am researching the system implement of android.view.animation.Animation.
I override the Animation.applyTransformation() method, and log the invoking interval time, it's about 16ms.
16ms' interval means 60fps. This make the animation plays smoothly.
But why is 16ms? Who control this?
If I implement a animation thread to implement custom animation, I usually do postDelayed(this, 16), so that my Thread will run at 60fps, each time post a message to Handler ,tell it to do some UI change on Main Thread.
How about android system?

I think you are looking for the Choreographer class:
Coordinates the timing of animations, input and drawing. The choreographer receives timing pulses (such as vertical synchronization) from the display subsystem then schedules work to occur as part of rendering the next display frame.

Related

where to put infinite loop in android app to handle tweens

I would like to make use of the universal tween engine in my pure android app, and understand that I will need to put a loop somewhere which will update the tweenmanager every frame. I have used this before in game projects where i have access to the game loop provided but in the case of a pure android application, where would I create this loop and what is the best way to handle this as my app is opened/closed/paused/resumed etc?
Am I best creating a new thread in the onResume method for each activity and starting the loop there and ending the loop in the onPause method? or is it better to create a class that acts as a sort of "Activity manager" and is always available? if so how would I do this?
I found some useful documentation on this at https://code.google.com/archive/p/java-universal-tween-engine/wikis/AndroidUI.wiki and It seems the 'correct' way to achieve this is to create a new loop for each activity in onResume() and end the loop in onPause()
There is an API available starting in API level 16 called Choreographer. This is the thing that keeps the main thread pumping events at 60 frames per second. You can register a callback to be executed with the next frame, then within that callback, register to run it again at the next frame. This is the most reliable way to get called at every frame with near-perfect timing (as long as the main thread is not being blocked in a way that would case frame loss).
Your callbacks will all be called on the main thread, so be careful yourself about blocking the main thread. So keep your work super fast.

Imageview doesn't update. I've tried to use `invalidate();` but that didn't work

I'm trying to change the imageview 3 times in a short period of time.
I want to set the image, have sheldon say "Bazinga", then change imageview directly after he the audio is completed. And then I want to do that a second time.
Note that the first image is already set before calling this function:
sound = MediaPlayer.create(this, R.raw.bazinga);
sound.start();
page.setImageResource(R.drawable.counttotwofirst);
while(sound.isPlaying()){}
sound.start();
page.setImageResource(R.drawable.counttotwosecond);
while(sound.isPlaying()){}
sound.release();
page.setClickable(true);
I've tried to use invalidate(); but that didn't work.
Is there anyway to force update or at least wait until the imageview has been updated?
How long time is there between updates if imageviews?
Is there some other view I should use instead?
You need to re-think the design a bit. I am guessing you are running all of that code on the main (UI) thread of your app. The problem is that although you are changing the image resource, you are then causing the UI thread to block (sitting in a while() loop), so the UI updates don't get performed until after your entire function returns. You probably need some more pieces to achieve the sound/animation effects you want. Off the top of my head, probably create a background thread for performing the sound loading/playback so that's not done on the UI thread. Also, instead of sitting in a while() loop until the sound finishes, it's better to have a callback notify you that playback has completed (take a look at MediaPlayer::setOnCompletionListener()).

Android : Combine normal widget and SurfaceView

I have create a screen with two kind of views : normal view (buttons to receive up/down action ) and surfaceview. The SurfaceView implements SurfaceHolder.Callback and run on another thread and have a method name Tick().
When those buttons receive action, they will call method Tick(), and I want this method will run same thread with SurfaceView (for synchronize purpose), but don't know how to.
Please give me some idea for my issues.
Thanks :)
If you really want to run Tick() method in separate thread which also draws on the surface you can use HandlerThread for it. So you will be able to create Handler for it and post runnables which will be executed in this thread. But this also will put some restrictions on your drawing routine - you need to prevent it from sleeping or waiting because thread need to process message queue.
But actually I suppose any other reasonable way of synchronization will be easier than running this method on the same thread.

Android animation causing "Activity idle timeout for History Record" on start up

I have been searching for an answer to this and while I can find others who have been seeing the same entries in the log cat none of the footprints seem to be similar to mine.
Basically I start an infinitely repeating animation as part of my activity start up. The screen is rendered properly, is responsive to all touch input but I get the following entries in my logcat:
08-17 16:03:25.910: WARN/ActivityManager(110): Launch timeout has expired, giving up wake lock!
08-17 16:03:25.972: WARN/ActivityManager(110): Activity idle timeout for HistoryRecord{4057ad58 com.companyname.dm/.ui.activities.home.HomeActivity}
I have read posts that state these entries are indeed just warnings to indicate the main thread looper has never become idle and not a problem if it is the intended mode of operation. However, besides that fact that it seems excessive that the small repeating animation (a scale/transform/alpha animation that repeats every 3 seconds) is filling the message queue, my main issue is that it is preventing the ability to create automated tests. We are trying to implement a test using robotium but the test will never start because of the idle timeout.
Not starting the animation will eliminate this problem, but is much more a workaround than a root cause solution. I am trying to understand if I am either not implementing my animations properly, if this is indeed just the expected behavior or if there is a way to ensure the connection the instrumentation/robotium will be established.
Any insight would be greatly appreciated! Thanks.
Try starting your animation in a new thread, if you do too much stuff in the onCreate method you will block the UI-thread in Android, and it could possibly lead to an ANR (Application not responding) if you take longer than 5 seconds before returning. By starting your animation in a new thread the onCreate will return and the system will be happy.
new Thread(new Runnable() {
public void run() {
//start animation.
}
}.start();
The code which is repainting to the screen need to be started in a different thread, else the main UI thread will never become idle, which is causing the problem.
You may have issues when interacting with the UI from another thread, for this you should look into AsyncTask which is actually what is used to compute/draw progress bars. The obscene number of warnings is most likely because the warnings are generated any time after X seconds, which is only limited by Android's checks.

Sleeping in onTouchEvent blocks onSensorChanged

I'm making an application which will utilize both touchevents and sensorevents. The problem with touchevents is that they fire off very often, and thereby consumes massive amounts of CPU time. The common solution is to do a Thread.sleep to make it cool down.
However, if one wants to use both the onTouchEvent and onSensorChanged in the same activity, applying the Thread.sleep hack will also slow down onSensorChanged. This is obviously caused by the two methods being called from the same (ui) thread.
Is there some way to call onTouchEvent from a different thread than the ui, so one could do the Thread.sleep trick without slowing down onSensorChanged as well?
"The common solution is to do a Thread.sleep to make it cool down."
Where did you hear that? Sleeping on the main thread (also called EDT - event dispatching thread) is not acceptable. Android is redrawing the screen and doing all kinds of tasks on this thread. Sleeping it can make it unresponsive and is IMHO a bad practice.
If onTouchEvent() are firing too often then just filter them in your code = do nothing if at least X amount of time has not passed since last event.
long lastTime = 0; // field in you class holding event handler
// inside your onTouchEvent handler
if(System.getCurrentTimeMillis() - lastTime < XXX)
return;
lastTime = System.getCurrentTimeMillis();

Categories

Resources