2013-05-20 27 views
0

我想在android中開發音頻處理相關的應用程序。我有一個線程(不是UI線程),我正在執行一個操作。我仍然需要在操作過程中更新操作結果。對於我正在使用的處理程序。我只是使用Toast在處理程序中顯示結果。截至目前,我的線程將繼續單獨運行,並且在顯示第一個結果之後線程不再運行,因爲結果沒有更新。我只是知道,在修改由此線程和UI共享的變量時,我需要同步這兩個線程。我對麼?如果是這樣,我該如何實現它?如何處理在UI線程和android中的另一個線程之間共享的變量?

謝謝!

編輯

我張貼這是在我的線和我的處理程序運行方法的一部分。

 while(fulldatabuffcnt+200<=fulldatabuffer.size()) 
     { 
      double[] windowdata=new double[200]; 
      classlabel=0; 
      //classlabel_new=0; 
      int windowcnt=0; 
       for (int h=fulldatabuffcnt;h<fulldatabuffcnt+200;h++) 
       { 
         windowdata[windowcnt]=fulldatabuffer.get(h); 
         windowcnt++; 
       } 

       MFCCcoeffs=mfcc_inst.getParameters(windowdata); 
       classlabel=likeli_ref.llhmain(MFCCcoeffs); 

      try { 
       out.writeInt(fulldatabuffer.size()); 

       } catch (IOException e1) 
       { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 

      classlabel_array[ecount]=classlabel; 
      ecount++; 

      if (ecount==25) 
       { 
         synchronized(SharedData.globalInstance) { 

          SharedData.globalInstance.classlabel_new =occurence(classlabel_array);//<--shared variable classlabel_new getting modified 
         } 
         try { 
          out_max.writeInt(SharedData.globalInstance.classlabel_new); 
          } catch (IOException e1) { 
           // TODO Auto-generated catch block 
           e1.printStackTrace(); 
          } 

         ecount=0; 
        uiCallback.sendEmptyMessage(0); 


       } 


     fulldatabuffcnt=fulldatabuffcnt+80; 
     } 
     if(fulldatabuffcnt+200>fulldatabuffer.size()){ 

      AppLog.logString("Setting calclating thread to null"); 
      calculatingThread = null; 
     } 
     try { 
      out.close(); 

      out_max.close(); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 

    } 


    private Handler uiCallback = new Handler() { 

     public void handleMessage (Message msg) { 
      int label_handler; 
      synchronized(SharedData.globalInstance) { 
       label_handler=SharedData.globalInstance.classlabel_new; 
      } 

      Toast.makeText(MFCC2Activity.this, "Classified label" +label_handler, Toast.LENGTH_SHORT).show();//<--trying to access classlabel_new 

     } 

    }; 

回答

1

是的,你應該同步,以確保您的UI線程不會訪問由自己的線程只進行部分設置變量。

我建議你有一個單例對象,包含你需要在兩個線程之間傳遞的所有變量/數據等。例如,假設你需要在你自己的線程和UI線程之間共享一個字符串和一個雙精度型。用單例創建一個類SharedData,例如

class SharedData { 
    public String aString; 
    public double aDouble; 
    public static SharedData globalInstance = new SharedData(); 
} 

然後在自己的線程,你想如果你那樣做,設置數據

synchronized(SharedData.globalInstance) { 
    SharedData.globalInstance.aString = "some string"; 
    SharedData.aDouble = 42.0; 
} 

,並在你的UI線程

String aString; 
double aDouble; 
synchronized(SharedData.globalInstance) { 
    aString = SharedData.globalInstance.aString; 
    aDouuble = SharedData.aDouble; 
} 
// do something with aString and aDouble 

,那麼就不是與UI線程正在讀取的部分設置數據有關的任何問題。

+0

感謝您的快速響應。我照你所說的做了,但仍然沒有改變。請通過我所做的編輯。 classlabel_new是在與處理程序共享的線程中得到修改的變量。 – user1957734

+0

據我所知,如果您已經使用線程安全方式共享您稱爲classlabel_new(SharedData類的字段)的int,那麼您做了什麼。我不完全確定你的代碼是做什麼的,但是我敢肯定,如果它仍然沒有達到你想要的效果,這不是與同步相關的問題。 – Stochastically

+0

好的。我不知道我是否能夠充分讓你理解這種情況,但是發生的情況是,只要在通過麥克風進行的錄製中檢測到語音活動,緩衝區fulldatabuffer就會被填充。這一步是由另一個線程完成的,上面代碼中顯示的這個線程對fulldatabuffer進行了某種處理。每當我評論顯示部分,即,uiCallback.sendEmptyMessage(0);一切都發生完美。 – user1957734

相關問題