You can use the Executor service abstraction like this,个
public abstract class AsyncTaskV2<Params, Progress, Result> {
public enum Status {
FINISHED,
PENDING,
RUNNING
}
// This handler will be used to communicate with main thread
private final Handler handler = new Handler(Looper.getMainLooper());
private final AtomicBoolean cancelled = new AtomicBoolean(false);
private Result result;
private Future<Result> resultFuture;
private ExecutorService executor;
private Status status = Status.PENDING;
// Base class must implement this method
protected abstract Result doInBackground(Params params);
// Methods with default implementation
// Base class can optionally override these methods.
protected void onPreExecute() {
}
protected void onPostExecute(Result result) {
}
protected void onProgressUpdate(Progress progress) {
}
protected void onCancelled() {
}
protected void onCancelled(Result result) {
onCancelled();
}
protected boolean isShutdown() {
return executor.isShutdown();
}
@MainThread
public final Future<Result> execute(@Nullable Params params) {
status = Status.RUNNING;
onPreExecute();
try {
executor = Executors.newSingleThreadExecutor();
Callable<Result> backgroundCallableTask = () -> doInBackground(params);
// Execute the background task
resultFuture = executor.submit(backgroundCallableTask);
// On the worker thread — wait for the background task to complete
executor.submit(this::getResult);
return resultFuture;
} finally {
if (executor != null) {
executor.shutdown();
}
}
}
private Runnable getResult() {
return () -> {
try {
if (!isCancelled()) {
// This will block the worker thread, till the result is available
result = resultFuture.get();
// Post the result to main thread
handler.post(() -> onPostExecute(result));
} else {
// User cancelled the operation, ignore the result
handler.post(this::onCancelled);
}
status = Status.FINISHED;
} catch (InterruptedException | ExecutionException e) {
Log.e("TAG", "Exception while trying to get result" + e.getMessage());
}
};
}
@WorkerThread
public final void publishProgress(Progress progress) {
if (!isCancelled()) {
handler.post(() -> onProgressUpdate(progress));
}
}
@MainThread
public final void cancel(boolean mayInterruptIfRunning) {
cancelled.set(true);
if (resultFuture != null) {
resultFuture.cancel(mayInterruptIfRunning);
}
}
@AnyThread
public final boolean isCancelled() {
return cancelled.get();
}
@AnyThread
public final Status getStatus() {
return status;
}
}
现在,就像异步任务一样,这个类有onPreExecute()
、onPostExecute()
和doInBackground()
个.你可以用publishProgress()
方法发布你的进展.
Here is how to use it,个
new AsyncTaskV2<Void, Integer, Void>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void unused) {
myDataBase.sendJsonToFile(path,"myFile"+".json");
for(int i=0;i<=100;i++){
publishProgress(x);
x++;
}
publishProgress();
return null;
}
@Override
protected void onProgressUpdate(Integer integer) {
super.onProgressUpdate(integer);
}
@Override
protected void onPostExecute(Void unused) {
super.onPostExecute(unused);
}
}.execute(null);