Make onSensorChanged not to slow UI - android

My app acquires data from accelerometer and the UI is not so responsive as it should be.
I suppose this is because SensorEventListener is called in the UI thread.
So I tried to create a new thread, with an inner class which implements the event listener and in the thread I registered the accelerometer.
Nevertheless the code was executed in the UI thread. So: how would you make onSensorChanged not slowing UI?

Don't do a lot inside the callback. When you are executing your code, you cannot get another update.
For example, when you have a sleep(500) in the onSensorChanged, you will not receive a new update for the comming 500 mili sec.
So start a new thread inside the onSensorChanged and do your stuff in there.

Related

Thread.Sleep issue android methods and asynctask

I am working on app that updates data for every 8 secs and the update was done using Async task. I am using loops to achieve this condition
while(const_val > update_val) {
new Asynctask().execute();
Thread.sleep(8000);
}
const_val will be constant and will be not be changed by any other methods.lets say this value will be 5.update_val will be updated and decremented when Asynctask is called and let's the value will be 10. So , the while loop executes until the condition is true and asynctask ,sleep are called .
When I use above while loop in a general method then UI gets locked and if I use the same loop in another asynctask there was an error saying "Only original thread that created a view hierarchy can touch its view "
You need to change your code to start the AsyncTask and have it provide an update via its onPostExecute() method. By calling Thread.sleep() you are sleeping the main thread (or UI thread) of your app, which is not good. You do not ever want to block the main thread. This article may help you better understand AsyncTask and threading in Android: http://po.st/Cei3m2
I don't think you should use a surrounding loop. Look at this example:
http://javatechig.com/android/progress-notification-in-android-example
the AsyncTask is a private inner class
the onPostExecute updates the UI with a message/cancels the load bar
This way you don't have to loop and the onCreate() can return instantly.

Android - how to run your sensor ( service, thread, activity )?

I'm writing a simple tilting game. Make a ball roll over the screen in the direction you tilt your phone.
So I downloaded an example on how to get the sensor data and that works fine (I use a rotation matrix to avoid the Euler angle problem). But then I tried to put it into a bigger app and I have some trouble getting it to work.
My first idea was to run the tilt sensor in a separate thread but
my class: public class TiltSensor extends Thread implements SensorEventListener
is not working to well.
I get one round of values then it stops.
How would you implement this app?
I don't want to block the UI thread so I'm thinking I need a separate thread (GameHandler) to run the game and then I call runOnUithread and from there invalidate the View. I'd also separate the board representation from the View so I'd represent the screen as a matrix and then the view would use that matrix to know how the screen should look.
But I am unsure what the best way to implement the TiltSensor. Should it run in a separate thread or the same thread as the GameHandler? How do I make sure the SensorManager actually calls the onSensorChanged in the GameHandler thread?
In my humble experience, you should:
A) Register your SensorListener on your main thread normally, but make it spawn two (or as needed) WorkerThreads on its constructor.
B) Get the looper reference of both threads, to keep them alive waiting for future requests.
B) Listen to your onSensorChanged on your main thread normally, but do NOTHING OTHER (this is important) then delegate a copy of the values to a new runnable object that will process your game logic.
C) Enqueue your new runnable object on your WorkerThread looper reference accordingly.
D) Make the runnables (that are already off your main thread) do what they have to do and synchronize changes to a singleton that may be consulted by who is interested in updating your views.

Threading events using GreenRobot EventBus

I've just started looking at GreenRobot's EventBus for Android and have a question about threading.
I have a long-running process that I'd like to run on a background thread which, when completed, updates the UI.
So something like:
public void onEventBackgroundThread(MyEvent event) {
doSomeLongRunningProcess();
updateUI();
}
Obviously updateUI() can't be called here because it would also run in the background.
So what would be the recommended way to handle this? Fire another event from within my onEventBackgroundThread() which will run on the UI thread? Or fire it from the long-running-process itself? Or is there a better pattern?
I would probably fire another event when you get the result.
public void onEventBackgroundThread(MyEvent event) {
doSomeLongRunningProcess();
EventBus.getDefault().post(new MyEventResult());
}
Be aware though: reading the docs, you find this:
BackgroundThread: Subscriber will be called in a background thread. If
posting thread is not the main thread, event handler methods will be
called directly in the posting thread. If the posting thread is the
main thread, EventBus uses a single background thread that will
deliver all its events sequentially. Event handlers using this mode
should try to return quickly to avoid blocking the background thread.
If you take a long time in this method, other EventBus callbacks will be delayed which will probably translate to an unresponsive application.
You probably want to use onEventAsync:
Async: Event handler methods are called in a separate thread. This is
always independent from the posting thread and the main thread.
Posting events never wait for event handler methods using this mode.
Event handler methods should use this mode if their execution might
take some time, e.g. for network access. Avoid triggering a large
number of long running asynchronous handler methods at the same time
to limit the number of concurrent threads. EventBus uses a thread pool
to efficiently reuse threads from completed asynchronous event handler
notifications.
I'd suggest firing another event which will be handled by onEventMainThread method.
This has a positive impact of the updateUI not being called at all if the receiver is already unregistered (e.g. activity unregistered because it was destroyed).

Implementing a cyclic executive in android?

I am writing an android app and I need to be able to do certain things periodically/continuously. I am coming from a C/C++ embedded firmware background and this new-fangled way of doing things is going to take some getting used to. It seems that there is no such thing as a "main loop" in Android, that everything is event-driven... I also understand that by default all code you write operates on the GUI thread, and I should probably make a new thread to execute the equivalent of a "main loop"...
So far what I have is an implementation of the AsyncTask class who's "doInBackground" method contains an infinite loop (my main loop), I create an instance of this class and run it immediately when my app starts. The problem I am having is in the interaction between this thread and the user interface... when something occurs in my main loop thread and I want to update the GUI understand that I must call "publishProgress", which is executed on the GUI thread. There are a few problems with this, primarily that many things I have tried to do in this "onProgressUpdate" method do not work, or do not occur in a predictable amount of time.
My question, is there a better way to accomplish what I am trying to do? In general, what do most people do when they have code that they want to run periodically and/or continuously while their application is running, code that must interact with the user interface in a timely manner (by timely I mean with zero delay).
Thank you.
public class MainLoopThread extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... arg0)
{
while(true)
{
//Do stuff
//Update GUI
publishProgress();
}
}
protected void onProgressUpdate(Void...voids)
{
//Update GUI
}
}
It is unclear what you are trying to do, however just let me say using AsyncTask in this way may have negative consequences.
AsyncTask internally uses a thread pool pattern for running the stuff from doInBackground(). On Android OS before 1.6 and starting from 3.0 the pool size is just 1, meaning no parallel computations for a bunch of AsyncTasks. More details on this here.
So, this may result that only this current AsyncTask is running, while others even if started will have to wait untill the current one is done.
Depending on your needs for things to be done periodically Android exposes:
AlarmManager
Handler - it allows to post a runnable on UI thread with a delay or periodically
Timer + Activity.runOnUiThread(Runnable action) inside of TimerTask
UPDATE: basing on your comments it looks like you need a Service, that starts a thread that periodically sends broadcasts with the data for UI. Then your UI (Activity) registers broadcast receivers to catch those broadcasts, extract the data and use for UI updates.
So your saying that onProgessUpdate() isn't working? That seems weird because it should.
Another option that you have is just to make a Thread that loops.
The trick is that if you want to update the UI thread you will have to make a call to view.post() and give it a runnable that will actually perform the update. The idea here is that you must schedule an update on the UI thread, you can't just take it and say NOW!

Does posting a Runnable with a Handler make things asynchronous?

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.

Categories

Resources