0

我在黑莓中使用线程来执行 Web 服务调用。我想在电话收到回复后立即收到通知。我正在使用

处理程序

在安卓。我没有在黑莓中找到类似的东西。

这是我用来运行线程的代码

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

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

线程完成运行后如何获得通知?我怎样才能在黑莓中做到这一点?谢谢

添加了更多信息:感谢您的回复。它的信息量很大。让我再解释一下我的问题。我有一个在线程上运行的 web 服务调用。一旦我从服务器收到回复,我想执行下一个函数(下一次调用服务器),它基于上一次调用的响应。所以我需要等到我得到回复。同时,我需要在屏幕上显示活动指示器。我在android中为此使用了处理程序。我在黑莓上寻找类似的东西。

4

3 回答 3

3

当我收到 Zach 的问题时 - 他询问如何在后台线程完成时执行一些涉及 UI 更改的代码(例如显示信息弹出窗口或关闭进度弹出窗口)。在 AndroidHandler上,在 UI 线程上创建的通常用于此目的。

在 BB 中,您可以使用类似于桌面 Java 上的 Swing 的另一种方式。当您需要在 UI 线程上执行一些代码时,您可以将其包装在 a 中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);
    }
});
于 2011-12-02T21:40:32.810 回答
3

所以你的问题本质上是这个

  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.
    }
}
于 2011-12-02T19:11:38.840 回答
1

Android 有非常丰富的多线程原语。但即使在 Blackberry 中,您也能以同样的优雅达到同样的效果。我在下面提供的解决方案与以前的解决方案基本相同,但有细微的变化。Waiter 线程可以替换为内置实用程序,以使用 UiApplicaiton 的 invokeLater 方法在 UI 线程上执行绘画。您实际上不需要“通知”任何人,只需在完成特定任务后更新 UI。检查文档以获取更多信息。

无论如何,您可以按照以下方式对代码进行建模:

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

请注意,我只提供了存根来让您了解如何完成。让我们知道怎么回事。

于 2011-12-04T00:56:15.150 回答