Reputation: 390
My android app Main Activity
is using a Thread
because a very "heavy" algorithm is being used and without threading it just stacks my UI and app.
That's my Thread
:
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimuth_angle = (float) (orientation[0]*180/Math.PI);
pitch_angle = (float) (orientation[1]*180/Math.PI);
roll_angle = (float) (orientation[2]*180/Math.PI);
p.setText(String.valueOf(pitch_angle));
r.setText(String.valueOf(roll_angle));
y.setText(String.valueOf(azimuth_angle));
new Thread(new Runnable() {
public void run()
{
try
{
Locations = Algo( pitch_angle, roll_angle,
azimuth_angle);
Thread.sleep(500);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
Problem:
Algo time is about 150-300 milliSeconds. I think this thread is activated again before Algo is finished. because the Thread
is executed each time onSensorChanged
running.
What can I do to make Algo return it's values to "Locations" as expected?
P.S Algo is tested on a Service
and works properly.
Upvotes: 0
Views: 72
Reputation: 6414
First of all, your Locations should be written from small letter, because it is a varibale. Second, if some variable is used by multiple threads it must be declared as volatile.
You could add a volatile boolean in which you store your thread state, for example true is running, flase is not. You need to set this variable to true just before you run your thread, and set it to false into finally statement in your thread. When the value of this variable is true (meaning that previous thread is running) you just return from this method, ignorig the event.
private volatile boolean heavyAlgRunning = false;
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimuth_angle = (float) (orientation[0]*180/Math.PI);
pitch_angle = (float) (orientation[1]*180/Math.PI);
roll_angle = (float) (orientation[2]*180/Math.PI);
p.setText(String.valueOf(pitch_angle));
r.setText(String.valueOf(roll_angle));
y.setText(String.valueOf(azimuth_angle));
if (heavyAlgRunning) return;
heavyAlgRunning = true;
new Thread(new Runnable() {
public void run()
{
try
{
Locations = Algo( pitch_angle, roll_angle,
azimuth_angle);
Thread.sleep(500);
}
catch (Throwable e)
{
// TODO Auto-generated catch block
Log.e("t","t",e);
//e.printStackTrace();
}
// finally {
// heavyAlgRunning =false;
// }
heavyAlgRunning =false;
}
}).start();
}
Upvotes: 1
Reputation: 2123
You need to lock your thread until it finishes equations. So you can try to add synchronized
section in try
statement or use one of thread system locks: https://stackoverflow.com/a/24582076/3345366
Upvotes: 1