1

2 つのスレッドを使用する Android アプリを作成しています。1 つは UI スレッドで、もう 1 つはサーバー通信を処理します。他のスレッドが指定された時間だけ待機し、到着したすべてのメッセージを処理してから再度待機することは可能ですか?

これは、さまざまなデータを収集して 1 つのセッションでサーバーに送信できるようにするために必要です。

HandlerThread でスレッドを作成しましたが、行き詰まりました。誰かが私を正しい方向に向けることができますか?

これは、2 番目のスレッド内で使用しているコードです。

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 の代わりに Thread を使用し、キューを使用することで問題を解決しました。

私はプログラミングが初めてなので、恐ろしいエラーをお詫びしますが、最終的に使用したコードを次に示します。

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();
            }

        } 
    }
}

PS これは私の最初の投稿でもあります。解決済みとマークする必要がありますか?どのように?

4

0 に答える 0