Работа с нитками в ежевике - PullRequest
       21

Работа с нитками в ежевике

0 голосов
/ 02 декабря 2011

Я использую потоки в Blackberry для выполнения вызовов веб-службы. Я хочу получать уведомления, как только звонок получает ответ. Я использовал

Обработчики

в андроиде. Я не нашел ничего похожего в ежевике.

Вот код, который я использую для запуска потока

class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }

Как я могу получить уведомление после завершения потока? Как я могу сделать это в ежевике? Спасибо

Добавлена ​​дополнительная информация: Спасибо за ваш ответ. Это правда познавательный. Позвольте мне объяснить немного больше по моей проблеме. у меня есть Вызов webservice, который выполняется в потоке. Как только я получу ответ с сервера Я хочу выполнить следующую функцию (следующий вызов на сервер), который основан на ответе от предыдущего вызова. Так что мне нужно подождать, пока я не получу ответ. Также в то же время мне нужно показать индикатор активности на экране. я был используя обработчик для этого в Android. Я ищу что-то подобное на ежевике.

Ответы [ 3 ]

3 голосов
/ 03 декабря 2011

Когда я получил вопрос Зака ​​- он спрашивает, как выполнить некоторый код, который включает изменения пользовательского интерфейса (что-то вроде отображения всплывающей информации или закрытия всплывающего окна) после завершения фонового потока.На Android Handler, созданный в потоке пользовательского интерфейса, часто используется для этой цели.

В BB вы можете использовать другой способ, аналогичный Swing на настольной Java.Когда вам нужно выполнить некоторый код в потоке пользовательского интерфейса, вы заключаете его в Runnable и переходите к одному из следующих методов:

// Puts runnable object into this application's event queue, 
// and waits until it is processed.
Application.invokeAndWait(Runnable runnable)

// Puts runnable object into this application's event queue.    
Application.invokeLater(Runnable runnable)

// Puts runnable object into this application's event queue 
// for repeated execution.
Application.invokeLater(Runnable runnable, long time, boolean repeat)

Так что поведение вышеупомянутых вызовов похоже на то, что Handler.post(Runnable r) (и тому подобное).

Обратите внимание, что вы всегда можете получить дескриптор вашего экземпляра Application с помощью статического вызова Application.getApplication().

Так что в конце фонаПоток это безопасно сделать что-то вроде этого:

Application.getApplication().invokeLater(new Runnable() {
    public void run() {
        progressScreen.close();
        Dialog.alert("I am finished!");
    }
});

Это похоже на Android:

handler.post(new Runnable() {
    public void run() {
        progressScreen.dismiss();
        showDialog(DIALOG_TASK_FINISHED_ID);
    }
});
3 голосов
/ 02 декабря 2011

Так что ваш вопрос по сути это

  1. Один поток выполняет работу, в то время как другой поток ожидает завершения
  2. Первый поток завершает работу и «уведомляет» второй поток.

Это простая проблема потребителя производителя. Вот код, как вы можете решить эту проблему.

 class JobResult
{
  boolean done = false;
}

JobResult result = new JobResult();

 class Worker extends Thread
{
    JobResult _result;
    public Worker( JobResult result )
    {
        _result = result
    }
    public void run()
    {
        // Do some very long job
        synchronized( _result )
        {
            // modify result
            _result.done = true;
            _result.notify();
        }
    }
}

public class Waiter extends Thread
{
    JobResult _result;
    public Waiter( JobResult result )
    {
        _result = result;
    }
    public void run()
    {
        synchroinzed( _result ){

            while(! _result.done)
            {

                this.wait();
            }
        }
        // Wait is over. You can do something now.
    }
}
1 голос
/ 04 декабря 2011

Android имеет много богатых многопоточных примитивов. Но вы можете добиться того же даже в Blackberry с равной элегантностью. Решение, которое я предлагаю ниже, по сути, такое же, как и в предыдущем случае, но с небольшими изменениями. Поток официанта может быть заменен встроенной утилитой для выполнения рисования в потоке пользовательского интерфейса с использованием метода invokeLater UiApplicaiton. На самом деле вам не нужно «уведомлять» кого-либо, а просто обновлять пользовательский интерфейс после выполнения определенной задачи. Проверьте документы для получения дополнительной информации.

В любом случае, вы можете смоделировать ваш код в соответствии с:

class ProgressScreen extends FullScreen
{
    LabelField _label;
    public void start()
    {
    }
    public void setMessage( final String message )
    {
    UiApplication.getApplication( 
            UiApplication.invokeLater( 
                new Runnable() {
                 _label.setText( message );
            }
        )
    );
    }

    public void dismiss()
    {
        this.close();
    }
}

interface WebserviceTask
{
    int STATUS_CONDITIONS_NOT_SATISFIED = -3;
    int STATUS_NET_ERR = -2;
    int STATUS_FAILURE = -1;
    int STATUS_SUCCESS =  0;

    public int invoke();

}

public class Updater extends Thread
{
    final int NUM_TASKS = 10;
    WebServiceTask tasks[] = new WebServiceTask[ NUM_TASKS ];
    WebServiceTask tasks[0] = new WebServiceTask(){
        public int invoke()
        {
            int retCode = 0;
            // invoke a particular web service
            return STATUS_SUCCESS;
        }
    }

    public void run()
    {
        ProgressScreen progress = new ProgressScreen();
        progress.start();
        for( int i=0; i < NUM_TASKS; i++ )
        {
            int retcode;
            WebServiceTask t = tasks[i];
            retcode = t.invoke();
            String mesg;
            switch( retcode )
            {
            case STATUS_SUCCESS: { mesg ="Task successfully completed!";} break;
            case STATUS_NET_ERR: { mesg ="Could not connect to network";} break;
            }
            progress.setMessage(message);
        }
        progress.dismiss();
    }
}

Обратите внимание, что я предоставил только заглушки, чтобы дать вам представление о том, как вы можете достичь. Дайте нам знать, как это происходит.

...