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();
Related
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.
My surfaceView is running in a thread because at times it's animated , however
most the time it just needs to be re-drawn once and left in response to some user interaction , but because its running in the thread onDraw is continually being called... the constant re-draws are slowing it down and making my phone warm :)
I would like to use invalidate(Rect) but can't see how to do this when the thread is controlling onDraw ...
Everything constantly redrawing can't be the way i should go , any help will be greatly appriciated ...
In your thread, you can call wait() after calling onDraw(). This will force the thread to sleep until prompted to continue working. Once the user has interacted and you want to resume animation, call notify() on the thread to wake it up and have it redraw.
If that doesn't exactly solve your problem, consider putting the wait() inside of an if statement so it will only happen after some condition is met.
I have created my own custom view class by extending "SurfaceView." I then override the onTouchEvent method. Two questions.
(1) Should I even both calling the super.onTouchEvent even though I handle everything (I think) I need? (2) Should have the work done in a new thread? I am receiving many Skipped 32 frames! The application may be doing too much work on its main thread Is the onTouchEvent called from the UI thread?
My view is nothing more than a joy stick and on the on touch event I simply move the coordinates of an object with 3 or 4 lines of code.
Here it is not necessarey to call superOnTouchEvnet.But remember that if you return false it wont work. so it is better to return super.OnTouchEvent after finishing task if you want to handle the event. If for some casees or for some input you dont want to handle the touch event then without using the super method just return false.
yes. this method is handled by main UI thread. so for long tasks use any safe methods like using different threads, asynctask or handler.post.
I am updating an activity's UI from a BroadcastReceiver that I register in the same activity. The API docs say:
[...] The function [onReceive()] is normally called within the main thread
of its process [...]
so I suppose updating the UI is okay.
The docs also say:
[...] you should never perform long-running operations in it (there is
a timeout of 10 seconds [...]
I am just setting some text on a TextView so I suppose that won't ever take longer than 10 seconds.
But, and here comes finally my actual question: Does it make any sense at all to add a Runnable to the main thread's message queue using a Handler, so that onReceive() can return immediately and the UI update happens at some later point in time, as the docs suggest:
There are two main uses for a Handler: (1) to schedule messages and
runnables to be executed as some point in the future; [...]
?
If you're just setting text on TextViews then you won't have issues. No need to over-complicate things with Handlers.
Though I will say that some people like using handlers just because it keeps things organized if multiple calls to a specific UI method need to be called. Using a handler will guarantee that that executed code will be initially placed on the UI thread, so it avoids having to check which thread you are running on.
The important thing to keep in mind is that all UI actions should be performed on the UI thread, and any sort of intensive processing should be done on a background thread.
Yes, using a Handler to schedule a Runnable is the standard.
I have a class that extends the Thread class and has its run method implemented as so.
public void run(){
while(!terminate){
if(paused){
Thread.yield();
}else{
accummulator++;
}
}
}
This thread is spawned from the onCreate method.
When my UI is hidden (when the Home key is pressed) my onPause method will set the paused flag to true and yield the tread. However in the DDMS I still see the uTime of the thread accumulate and its state as "running".
So my question is. What is the proper way to stop the thread so that it does not use up CPU time?
It is actually bad practice to keep a thread running after onPause. The reason is that after onPause your application may drop out of memory at any time without your being able to know, therefore you will not be able to clean up after yourself.
The proper way to do it is stopping the thread onPause and recreating it onResume. If you need state you can use Android's built in saveState methods or settings or whichever to keep that.
Even though you're calling thread.yield(), you're inside of a while() loop which is probably looping thousands of time per second, each time calling .yield() but the fact that it's looping out of control means that it's using up resources. If you put a Log.d message in there you'll see what I mean.
I recommend using a Thread.sleep() instead of Thread.yield(). The reason being, while a thread is sleeping it is yielded. Plus with the sleep you get the added benefit of slowing down the while() and not using up resources. A sleep interval of 500ms should be sufficient =)
Your paused variable is most likely being cached thread-locally. This is because it's only being read and not changed in the loop. So what is happening is that compiler/interpreter/jitter optimizes by only reading the variable once and then only executing the else branch. You need to mark that field as volatile for the pause variable to be read every iteration through the loop. Check out the documentation of the volatile keyword. Here's some info about threading and some info about synchronization and concurrency.