2015-05-28 58 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爲我工作。 –