BlackBerry类相当于AsyncTask?

Kar*_*mil 6 java multithreading android blackberry android-asynctask

我的要求是拥有一个在BlackBerry设备和服务器之间维护套接字连接的线程,并交换命令,类似于请求和响应.

我的问题是,我需要这个线程在后台运行所有的时间,并保持提供给用户的UI.因此,当有来自服务器的命令时,该线程会解析它并更新UI,如果有来自BlackBerry用户的操作,它会将其发送到服务器,服务器依次处理它.

我使用Android开发了相同的应用程序AsyncTask并且运行良好.但是在BlackBerry中,由于没有这样的类,我使用了invokeLater()选项.通信在服务器和BB设备之间正常工作,但UI在BlackBerry上被冻结.

任何人都知道如何做到这一点?

Nat*_*ate 12

Vishal走在正确的轨道上,但需要更多才能与Android相匹配AsyncTask.由于BlackBerry上的Java 1.3无法使用枚举和泛型,因此无法完美匹配Android API.

但是,你可以做这样的事情(没有经过测试......这只是你的起点):

import net.rim.device.api.ui.UiApplication;

public abstract class AsyncTask {

    public static final int FINISHED = 0;
    public static final int PENDING = 1;
    public static final int RUNNING = 2;

    private int _status = PENDING;
    private boolean _cancelled = false;
    private Thread _worker;

    /** subclasses MUST implement this method */
    public abstract Object doInBackground(Object[] params);

    protected void onPreExecute() {
        // default implementation does nothing
    }
    protected void onPostExecute(Object result) {
        // default implementation does nothing
    }
    protected void onProgressUpdate(Object[] values) {
        // default implementation does nothing
    }
    protected void onCancelled() {
        // default implementation does nothing
    }
    protected void onCancelled(Object result) {
        onCancelled();
    }

    public final int getStatus() {
        return _status;
    }

    public final boolean isCancelled() {
        return _cancelled;
    }

    public final boolean cancel(boolean mayInterruptIfRunning) {
        if (_status == FINISHED || _cancelled) {
            return false;
        } else {
            _cancelled = true;
            if (mayInterruptIfRunning && _status == RUNNING) {
                // NOTE: calling Thread.interrupt() usually doesn't work
                //   well, unless you don't care what state the background
                //   processing is left in.  I'm not 100% sure that this is how
                //   Android's AsyncTask implements cancel(true), but I 
                //   normally just cancel background tasks by letting the
                //   doInBackground() method check isCancelled() at multiple
                //   points in its processing.
                _worker.interrupt();
            }
            return true;
        }
    }

    protected final void publishProgress(final Object[] values) {
        // call back onProgressUpdate on the UI thread
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run() {
                onProgressUpdate(values);
            }
        });
    }

    private void completeTask(final Object result) {
        // transmit the result back to the UI thread
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run() {
                if (isCancelled()) {
                    onCancelled(result);
                } else {
                    onPostExecute(result);
                }
                // TODO: not sure if status should be FINISHED before or after onPostExecute()
                _status = FINISHED;
            }
        }); 
    }

    public AsyncTask execute(final Object[] params) throws IllegalStateException {
        if (getStatus() != PENDING) {
            throw new IllegalStateException("An AsyncTask can only be executed once!");
        } else {
            try {
                onPreExecute();

                _worker = new Thread(new Runnable() {
                    public void run() {
                        try {
                            // run background work on this worker thread
                            final Object result = doInBackground(params);
                            completeTask(result);
                        } catch (Exception e) {
                            // I believe if Thread.interrupt() is called, we'll arrive here
                            completeTask(null);
                        }
                    }
                });
                _status = RUNNING;
                _worker.start();
            } catch (Exception e) {
                // TODO: handle this exception
            }
        }

        return this;
    }

}
Run Code Online (Sandbox Code Playgroud)

此外,重要的是要记住Android的AsyncTask的线程规则,它也适用于上述实现:

线程规则 有必须遵循此类才能正常工作的几个线程规则:

  • 必须在UI线程上加载AsyncTask类.这是从JELLY_BEAN开始自动完成的.

  • 必须在UI线程上创建任务实例.

  • 必须在UI线程上调用execute(Params ...).

  • 不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params ...),onProgressUpdate(Progress ...).

  • 该任务只能执行一次(如果尝试第二次执行,则会抛出异常.)