2012-10-11 41 views
0

我寫過一個文件緩存,允許從網絡加載文件。活動向該文件緩存發送請求,並提供在請求的文件已下載時得到通知的BroadcastReceiver的名稱和操作。如何從正在運行的線程發送廣播

此緩存正在工作,但它有一個小缺點。

如果下載隊列中有很多文件,則在處理完所有下載之後立即通知活動。我想爲每個下載的文件發送廣播。

這是精簡的代碼。當前處理程序在處理完Thread.run()中的所有文件後被觸發。我想從運行中發送廣播。在Thread.run()期間做什麼(發送廣播)的首選方法是什麼?

非常感謝提前。

public abstract class MyFileCache { 

    private static class CacheElement { 
     private File file; 
    } 

    private static class QueueElement { 
     private long action; 
     private String filename = ""; 
     private long id; 
     private String receiver = ""; 
    } 

    private static class ProcessedElement { 
     private long action; 
     private File file; 
     private long id; 
     private String receiver = ""; 
    } 

    private Map<String, CacheElement> cache = new ConcurrentHashMap<String, CacheElement>(); 
    private Context context; 
    private Map<String, ProcessedElement> processed = new ConcurrentHashMap<String, ProcessedElement>(); 
    private Map<String, QueueElement> queue = new ConcurrentHashMap<String, QueueElement>(); 

    public MyFileCache(Context context) { 
     this.context = context; 
    } 

    private void doThread() { 
     final Handler handler = new Handler() { 

      @Override 
      public void handleMessage(Message message) { 

       try { 
        for (Map.Entry<String, ProcessedElement> entry : processed.entrySet()) { 
         // Currently: Processing all fetched files at once 
         // Send for all entries a broadcast to the requesting activities 
         ProcessedElement processedElement = entry.getValue(); 
         if (processedElement != null && processedElement.receiver != null) { 
          processSendBroadcast(processedElement.receiver, 
            processedElement.action, processedElement.id); 
         } 

         deleteFromProcessed(entry.getKey()); 
        } 
       } catch (NullPointerException exception) { 
       } 
      } 
     }; 

     new Thread() { 

      @Override 
      public void run() { 
       for (Map.Entry<String, QueueElement> entry : queue.entrySet()) { 
        QueueElement queueElement = entry.getValue(); 
        if (queueElement != null) { 
         File file = fetch(entry.getKey(), queueElement.id, queueElement.filename, 
           queueElement.receiver, queueElement.action); 
         if (file != null) { 
          // Wish: Sending a broadcast to the requesting activity for each fetched file 
         } 
        } 
       } 

       handler.sendEmptyMessage(0); 
      } 
     }.start(); 
    } 

    private void deleteFromProcessed(String url) { 
     if (processed.containsKey(url)) { 
      ProcessedElement processedElement = processed.get(url); 
      if (processedElement != null) { 
       processed.remove(url); 
      } 
     } 
    } 

    // Send broadcast 
    private void processSendBroadcast(String receiver, long action, long id) { 
     Intent intent = new Intent(); 
     intent.putExtra("ACTION", action); 
     intent.putExtra("ID", id); 
     intent.setAction(receiver); 
     context.sendBroadcast(intent); 
    } 
} 

回答

0

我會說一個「FILE_COMPLETED」動作發送Intent,並增加額外的與文件名稱的字符串,並把所有的活動註冊與同一動作BroadcastReceiver但內比較是否將字符串額外Intent與活動所需的文件相匹配。

+0

謝謝,但那不是問題。請查看顯示的代碼(向下滾動) - 它顯示在處理完所有文件後,我已經發送了一個意圖。我的問題是:如何在每個單獨條目的Thread.run()處理過程中發送該Intent?我需要在該消息中添加一些字符串或對象,並且我不知道這是否可行,以及它是如何工作的。 –

+0

您是否在每次輸入後檢查if(processedElement!= null && processedElement.receiver!= null)? –

+0

就這麼簡單?我一直認爲發送廣播會感染UI-Thread,因此在單獨的Thread(非UI線程)內是不可能的。非常感謝這個提示。 –