Java 如何使线程休眠一段时间,然后处理所有消息?
我正在编写一个使用两个线程的Android应用程序。一个是UI线程,另一个处理服务器通信。另一个线程是否可以等待指定的时间,然后处理所有到达的消息,然后再次等待 我需要这个,这样我就可以收集不同的数据并在一个会话中将其发送到服务器 我已经用HandlerThread构建了我的线程,但现在我被卡住了。谁能给我指一下正确的方向吗 这是我在第二个线程中使用的代码:Java 如何使线程休眠一段时间,然后处理所有消息?,java,android,multithreading,Java,Android,Multithreading,我正在编写一个使用两个线程的Android应用程序。一个是UI线程,另一个处理服务器通信。另一个线程是否可以等待指定的时间,然后处理所有到达的消息,然后再次等待 我需要这个,这样我就可以收集不同的数据并在一个会话中将其发送到服务器 我已经用HandlerThread构建了我的线程,但现在我被卡住了。谁能给我指一下正确的方向吗 这是我在第二个线程中使用的代码: public synchronized void waitUntilReady() { serverHandler = n
public synchronized void waitUntilReady() {
serverHandler = new Handler(getLooper()){
public void handleMessage(Message msg) { // msg queue
switch(msg.what) {
case TEST_MESSAGE:
testMessage(msg);
break;
case UI_MESSAGE:
break;
case SERVER_MESSAGE:
break;
default:
System.out.println(msg.obj != null ? msg.obj.getClass().getName() : "is null");
break;
}
}
};
}
编辑:
我通过使用线程而不是HandlerThread并使用队列解决了我的问题
我是编程新手,所以我为任何令人讨厌的错误道歉,但以下是我最终使用的代码
public class ServiceThread extends Thread {
// TODO maybe set the thread priority to background?
static ServiceThread sThread = new ServiceThread(); // service thread instance
private volatile Handler mainHandler;
//
public Thread mainThread;
private boolean OK = true;
public Queue<MessageService> msgQueue;
private ThreadPoolExecutor exec;
private ServiceThread() { }
@Override
public void run() {
synchronized (this){
msgQueue = new ConcurrentLinkedQueue<MessageService>();
notifyAll();
}
mainHandler = new Handler(Looper.getMainLooper());
ThreadPoolExecutor exPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
exec = exPool;
// MAIN LOOP
try {
while(OK) {
getMessagesFromQueue();
Thread.sleep(3000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//end of loop
}
public void ProcessMessage(MessageService message) {
System.err.println("ProcessMessage with command: " + message.command);
}
/** Called from the Main thread. Waits until msgQueue is instantiated and then passes the reference
* @return Message Queue
*/
public Queue<MessageService> sendQueue() {
synchronized (this){
while(msgQueue == null) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block -- move the try block!
e.printStackTrace();
}
}
}
return msgQueue;
}
public void setOkFalse () {
if (OK == true)
OK = false;
}
// Message handling methods
/** Priority message from UI thread, processed in another thread ASAP.
* Should be used on commands like getBigPicture or getPics when cached pics are running out
* or upload picture etc.
* @param message - Message should always be MessageService class
* TODO check that it really is.
*/
public void prioTask (MessageService message) {
final MessageService taskMsg = message;
Runnable task = new Runnable() {
@Override
public void run(){
ProcessMessage(taskMsg);
}
};
exec.execute(task);
}
/**
* Gets messages from queue, puts them in the list, saves the number of messages retrieved
* and sends them to MessageService.handler(int commands, list messageList)
* (method parameters may change and probably will =) )
*/
public void getMessagesFromQueue() {
int commands = 0;
ArrayList <MessageService> msgList = new ArrayList <MessageService>();
while(!msgQueue.isEmpty()) {
if(msgQueue.peek() instanceof MessageService) {
//put into list?
msgList.add(msgQueue.remove());
commands++;
} else {
//Wrong type of message
msgQueue.remove();
System.err.println("getMessagesFromQueue: Message not" +
" instanceof MessageService, this shouldn't happen!");
}
}
if (commands > 0) {
HTTPConnection conn;
try {
conn = new HTTPConnection();
MessageService.handleSend(commands, msgList, conn);
conn.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
公共类ServiceThread扩展线程{
//TODO是否可以将线程优先级设置为后台?
静态ServiceThread sThread=新ServiceThread();//服务线程实例
私有易失性处理程序mainHandler;
//
公共线程主线程;
私有布尔OK=true;
公共队列msgQueue;
私有线程池执行器执行器;
私有ServiceThread(){}
@凌驾
公开募捐{
已同步(此){
msgQueue=新的ConcurrentLinkedQueue();
notifyAll();
}
mainHandler=新处理程序(Looper.getMainLooper());
ThreadPoolExecutor exPool=(ThreadPoolExecutor)Executors.newFixedThreadPool(2);
exec=exPool;
//主回路
试一试{
while(OK){
getMessagesFromQueue();
睡眠(3000);
}
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
//循环结束
}
public void ProcessMessage(MessageService message){
System.err.println(“带有命令的ProcessMessage:”+message.command);
}
/**从主线程调用。等待msgQueue实例化,然后传递引用
*@返回消息队列
*/
公共队列sendQueue(){
已同步(此){
while(msgQueue==null){
试一试{
等待();
}捕捉(中断异常e){
//TODO自动生成的捕捉块--移动try块!
e、 printStackTrace();
}
}
}
返回msgQueue;
}
public void setOkFalse(){
如果(OK==真)
OK=假;
}
//消息处理方法
/**来自UI线程的优先级消息,尽快在另一个线程中处理。
*当缓存的图片用完时,应该在诸如getBigPicture或getPics之类的命令上使用
*或上传图片等。
*@param message-message应始终为MessageService类
*要检查它是否真的是。
*/
public void prioTask(MessageService message){
最终消息服务任务消息=消息;
Runnable任务=新的Runnable(){
@凌驾
公开募捐{
ProcessMessage(taskMsg);
}
};
执行(任务);
}
/**
*从队列中获取消息,将它们放入列表中,保存检索到的消息数
*并将它们发送到MessageService.handler(int命令,list messageList)
*(方法参数可能会更改,并且可能会=))
*/
public void getMessagesFromQueue(){
int命令=0;
ArrayList msgList=新的ArrayList();
而(!msgQueue.isEmpty()){
if(msgQueue.peek()MessageService实例){
//列入名单?
添加(msgQueue.remove());
命令++;
}否则{
//错误类型的消息
msgQueue.remove();
System.err.println(“getMessagesFromQueue:MessageNot”+
“instanceof MessageService,这不应该发生!”);
}
}
如果(命令>0){
http连接接头;
试一试{
conn=新的HTTPConnection();
MessageService.handleSend(命令、msgList、conn);
连接断开();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
}
这也是我在这里的第一篇文章。我应该把它标记为解决了还是什么?如何使用?您可能希望使用定时器/定时器任务,而不是文字睡眠。如果您的事件需要唤醒休眠设备或在应用程序尚未运行时重新启动应用程序,您可能需要使用报警机制。因此,我应该在消息到达时读取消息,然后将它们转发给计时器,计时器会按预定的间隔将它们发送到服务器?或者有没有一种方法可以让消息队列等待使用计时器进行消息处理?昨晚,我尝试在消息处理之后添加sleep(),但是很明显,消息队列在每条消息之后都会暂停,并且没有一次处理所有到达的消息。