Java 如何从正在运行的线程中发送广播

Java 如何从正在运行的线程中发送广播,java,android,multithreading,handler,Java,Android,Multithreading,Handler,我编写了一个文件缓存,允许从web加载文件。活动将请求发送到此文件缓存,并提供BroadcastReceiver的名称和操作,当下载请求的文件时,该接收者将收到通知 此缓存正在工作,但有一个小缺点 如果下载队列中有大量文件,则在处理所有下载后,会立即通知活动。我想为每个下载的文件发送广播 这是精简的代码。当前,在处理Thread.run()中的所有文件后,将触发一个处理程序。我想在跑步时发送广播。在Thread.run()期间,执行某些操作(发送广播)的首选方式是什么 非常感谢 public a

我编写了一个文件缓存,允许从web加载文件。活动将请求发送到此文件缓存,并提供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);
    }
}
公共抽象类MyFileCache{
私有静态类缓存元素{
私有文件;
}
私有静态类队列元素{
私人长期行动;
私有字符串filename=“”;
私人长id;
专用字符串接收器=”;
}
私有静态类ProcessedElement{
私人长期行动;
私有文件;
私人长id;
专用字符串接收器=”;
}
私有映射缓存=新的ConcurrentHashMap();
私人语境;
已处理私有映射=新ConcurrentHashMap();
私有映射队列=新的ConcurrentHashMap();
公共MyFileCache(上下文){
this.context=上下文;
}
私有void doThread(){
最终处理程序=新处理程序(){
@凌驾
公共无效handleMessage(消息消息){
试一试{
for(Map.Entry:processed.entrySet()){
//当前:一次处理所有获取的文件
//向请求活动发送所有条目的广播
ProcessedElement ProcessedElement=entry.getValue();
if(processedElement!=null&&processedElement.receiver!=null){
processSendBroadcast(processedElement.receiver,
processedElement.action,processedElement.id);
}
deleteFromProcessed(entry.getKey());
}
}捕获(NullPointerException异常){
}
}
};
新线程(){
@凌驾
公开募捐{
对于(Map.Entry:queue.entrySet()){
QueueElement=entry.getValue();
if(queueElement!=null){
File File=fetch(entry.getKey()、queueElement.id、queueElement.filename、,
queueElement.receiver,queueElement.action);
如果(文件!=null){
//愿望:为每个获取的文件向请求活动发送广播
}
}
}
handler.sendEmptyMessage(0);
}
}.start();
}
私有void deleteFromProcessed(字符串url){
if(processed.containsKey(url)){
ProcessedElement ProcessedElement=processed.get(url);
if(processedElement!=null){
已处理。删除(url);
}
}
}
//发送广播
私有void processSendBroadcast(字符串接收器、长操作、长id){
意图=新意图();
意图。额外(“行动”,行动);
意向。额外(“ID”,ID);
意图。设置动作(接收器);
发送广播(意图);
}
}

我想说发送一个带有“FILE\u COMPLETED”操作的
意图,并在文件名中添加一个额外的字符串,让您的所有活动使用相同的操作注册一个
BroadcastReceiver
,但比较
意图中的额外字符串是否与活动所需的文件匹配。

谢谢,但这不是问题所在。请查看显示的代码(向下滚动)-它显示在处理完所有文件后,我已经发送了一个意向。我的问题是:在Thread.run()处理每个条目时,如何发送该意图?我需要在该消息中放入一些字符串或对象,但我不知道它是否有效以及如何工作。您是否检查过它在每个条目后是否进入if(processedElement!=null&&processedElement.receiver!=null)中?很简单吗?我一直认为发送广播会感染UI线程,因此不可能从单独的线程(非UI线程)中发送广播。非常感谢你的建议。也许有更深刻的解释,但我能说的是它是有效的。我将它们从甚至没有活动的进程发送到主UI线程。