ヴィシャルは正しい軌道に乗っているが、もう少しは、AndroidのAsyncTask
を一致させるために必要とされています。 enumとジェネリックスは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;
}
}
はまた、それはAndroidのために心の中でスレッドのルールを維持することが重要ですあまりにも、上記の実装に適用されますAsyncTask、:
スレッディング規則 fは従わなければならないいくつかのスレッドのルールがあります。またはこのクラスが正しく動作するようにします。
AsyncTaskクラスは、UIスレッドにロードする必要があります。これはJELLY_BEANの時点で自動的に となります。
タスクインスタンスは、UIスレッド に作成する必要があります。
UIスレッドでexecute(Params ...)を呼び出す必要があります。
手動でonPreExecute()、onPostExecute(Result)、 doInBackground(Params ...)、onProgressUpdate(Progress ...)を呼び出さないでください。
タスクは一度だけ実行することができます( 第二の実行が試行された場合、例外がスローされます。)
私は、昔ながらのJavaスレッドを使用することになり... – Lawrence
コンシューマー/プロデューサーの問題:http://en.wikipedia.org/wiki/Producer-consumer_problem –
私は実際にこのアプローチが本当に好きです。 APIを模倣しようとすると、私のコードの多くはAndroidとBlackBerryの間で再利用できることがわかりました。私はこれをいくつかの一般的なクラスでやった。 – Nate