Digol
Digol

Reputation: 390

Method execution on a Thread - not being executed / ending before finish

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

Answers (2)

Krzysztof Cichocki
Krzysztof Cichocki

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

anil
anil

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

Related Questions