0

對於我的應用我要跑兩個操作,無論是異步的,:如何同步2個異步線程/任務

  1. 從文件中讀取(我使用這個文件來模擬從數據總線讀) - 異步因爲我不知道「何時」在公共汽車上到達新的信息/字符。我搜索特定的序列字符,例如frame start_bytes =「xx」,後面的4個字節是我等待的「數據」。

  2. 將數據讀取/更新到Firebase,具體取決於從文件中讀取的「數據」 - 由於addValueEventListener的使用而導致的異步操作。

我想一個信號量/互斥機制或一個簡單的布爾標誌,一個任務信號,另一種是新的數據必須保存/更新到火力地堡。

如何將這兩個操作同步(通過將它們嵌入到Task/AsyncTask/Thread中)?

我跑了一個搜索這些主題,但我發現與UI,ProgressBars等相關的例子..不適合我的情況。在火力地堡

myRefDevices.addValueEventListener(new ValueEventListener() { 
       // addValueEventListener 
       // This method is called once with the initial value and again 
       // whenever data at this location is updated. 
       @Override 
       public void onDataChange(DataSnapshot dataSnapshot) { 
        boolean    bChildFound   = false; 
        DatabaseReference dbrefChildFound; 

        final CDeviceStatus obj_new = new CDeviceStatus(); 

        for(DataSnapshot val : dataSnapshot.getChildren()) 
        { 
         if(val.getKey().contentEquals(MAC_ADDRESS[ iIterator ])) 
         { 
          bChildFound = true; 

          dbrefChildFound = val.getRef(); 

          obj_new.setiAvailable_A(val.getValue(CDeviceStatus.class).getiAvailable_A() + 1); 

          obj_new.setsID(val.getValue(CDeviceStatus.class).getsID()); 

          dbrefChildFound.setValue(obj_new); 
         } 
        } 

        if(!bChildFound) 
        { 
         Log.d("child=" + MAC_ADDRESS[ iIterator ], "not found"); 
        } 


        if(++iIterator == 16) 
        { 
         iIterator = 0; 
        } 
       } 

       @Override 
       public void onCancelled(DatabaseError databaseError) { 

       } 

      }); 

讀/更新數據從文件中讀取:

try { 
    // open input stream text file for reading 
    Resources res = getResources(); 
    InputStream instream = res.openRawResource(R.raw.simulated_bus); 

    // we convert it to bufferred input stream 
    BufferedInputStream bistreamSimulatedBus = new BufferedInputStream(instream); 

     try{ 
      // if we want to stop reading from the file/simulated bus for whatever reason.. 
      boolean bStayInLoop   = true; 

      while ((bistreamSimulatedBus.available() > 0) && bStayInLoop) 
      { 
       try { 
        // throw new InterruptedException(); 
        char c = (char) bistreamSimulatedBus.read(); 

        if(COUNT_CHARACTERS_NEWLINE) 
        { 
         if ('\n' == c){ 
          // we can count how much NewLine character we have 
          //iNL_Counter++; 
         } 
        } 

       ... 

       } 
       catch (InterruptedException e) { 
        throw new RuntimeException(e); 
       } 
      } 
     } catch (IOException e) { 
       throw new RuntimeException(e); 
     } 
     finally { 
       // release any resource associated with streams 
       if (null != instream) { 
        instream.close(); 
       } 

       if (null != bistreamSimulatedBus) { 
        bistreamSimulatedBus.close(); 
       } 
      } 
     } 
    catch (Exception e) { 
     throw new RuntimeException(e); 
    } 

謝謝。

回答

2

讓我們打破的解決方案是這樣的:

的基礎

你有兩個操作:o1o2。您希望在第一個操作完成後立即執行第二個操作。

It 顯然在我看來你需要一個event-driven解決方案在這裏。

方法

使用Publisher/Subscriber設計模式的概念,可以使o1Initiator是事件的Publisher。然後,當這個特定的操作完成時,讓我們稱之爲Subscriber的其他類(活動,片段,服務)notify

代碼

以下行添加到您的build.gradle (app-level)

compile 'org.greenrobot:eventbus:3.0.0' 

然後,只需創建一個簡單的Plain Old Java Object (POJO)代表自己活動。

public class RequestCompletedEvent{ // add constructor and anything you want} 

接下來,Publish事件,您只需撥打post(POJO instance)這樣的:

EventBus.getDefault().post(new RequestCompletedEvent(true)); 

然後,終於,在Subscriber類,只需監聽通過添加以下代碼行通知:

@Override 
public void onStart() { 
    super.onStart(); 
    EventBus.getDefault().register(this); 
} 

@Override 
public void onStop() { 
    super.onStop(); 
    EventBus.getDefault().unregister(this); 
} 

然後仍然是相同的類中,使用Subscribe註解來捕獲任何信號:

@Subscribe 
public void onEvent(RequestCompletedEvent event) { 
    /* Do something */ 
    //trigger the second operation here; 
    startOperationTwo(); 
} 

摘要

這將有助於在這裏指出,要退出這個功能的最簡單的方法是使用async任務(的AsyncTask子類)來讀取你的文件,並順利完成時,內onPostExecute(),您可以通知Subscriber啓動下一個操作。

我希望這有助於;還有祝你好運!讓我知道你是否需要進一步的幫助!