2015-05-28 45 views
0

我的Android应用程序Main Activity正在使用Thread,因为正在使用非常“繁重”的算法,并且没有线程堆叠我的UI和应用程序。 这是我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(); 
     } 

问题: ALGO时间大约为150-300毫秒。我认为这个线程在Algo完成前被再次激活。因为Thread每次都在执行onSensorChanged运行。 我能做些什么来使Algo按照预期将它的值返回到“Locations”?

P.S Algo在Service上测试并正常工作。

回答

1

首先,您的位置应该从小写字母开始,因为它是一个varibale。其次,如果某个变量被多个线程使用,则必须将其声明为volatile。

您可以添加一个挥发性布尔值来存储线程状态,例如true正在运行,flase不是。您需要在运行线程之前将此变量设置为true,并在您的线程中将其设置为false成为finally语句。当这个变量的值为真(意味着前一个线程正在运行)时,您只需从此方法返回,忽略该事件。

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(); 
     } 
+0

首先感谢告诉我View查看变量需要非大写字母。第二,我使用阿尼尔说同步,那底座我的问题。我试着给你添加heavyAlgRunning,它使我的方向取样,并且根本不计算算法。你知道为什么吗? –

+0

只是调试它,似乎最后不要改变heavyAlgRinning。 –

+0

试试这个改变后的版本,并发布你将在logCat中的任何异常 –

1

你需要锁定你的线程直到它完成方程。因此,您可以尝试在try声明中添加​​部分或使用其中一个线程系统锁:https://stackoverflow.com/a/24582076/3345366

+0

Anil谢谢你这个好的解决方案它正在工作。我可以得到计算的值并显示它们。我的错误也是使用一个对象来激活我的算法inter方法,所以我删除了它们。现在洞的事情正在工作,但超级慢。你有什么想法让它更快?也许可以为.setText行创建更多的线程? –

+0

首先,从代码中移除'Thread.sleep') – anil

+0

我之前删除了这个,因为synchronized为我工作。 –