I’ve written a filecache that allows to load files from the web. Activities send requests to this filecache and give the name and action of a BroadcastReceiver that get’s notified when the requested file has been downloaded.
This cache is working but it has a small drawback.
If there are lots of files in the download queue the activities are notified at once after processing all downloads. I would like to send the broadcast for each downloaded file.
Here’s the stripped down code. Currently a Handler gets fired after processing all the files in the Thread.run(). I would like to send the Broadcast from within the run. What would be the prefered way to do something (send a Broadcast) during Thread.run()?
Many thanks in advance.
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);
}
}
I would say sending an
Intentwith a “FILE_COMPLETED” action, and adding a String extra with the file’s name and have all your activities register aBroadcastReceiverwith that same action but compare whether or not the String extra within theIntentmatches the file that activity wanted.