我用AsyncTask创建了一个小型安卓项目。它模拟一个耗时的任务。
请检查我的代码,并告诉我,你会以不同的方式做什么,以及为什么。欢迎评论,不特定于Android,而是一般的软件开发。
CounterTask.java:
package my.tasks;
import java.util.Random;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
/**
* @author 2
*
* Simulates a time consuming task, counts in the background from 0 to
* the given value in first parameter. Its progress is published via an
* integer which is a percentual value 0..100. The task may not
* complete, it may fail or it may be cancelled by the user. In case of
* success it returns true.
*/
public class CounterTask extends AsyncTask<Integer, Integer, Boolean> {
private static final long DELAY = 100;
private static final int PROBABILITY_TO_FAIL_EVERY_STEP = 1;
private static final String TAG = "CounterTask";
private ProgressDialog progressDialog;
private Random random;
/**
* @param progressDialog
* a ProgressDialog the task can use to display its progress.
*/
public CounterTask(ProgressDialog progressDialog) {
this.progressDialog = progressDialog;
this.progressDialog.setMax(100);
this.random = new Random();
}
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#doInBackground(Params[])
*
* Set params[0] to the maximum value you want the task to count to.
*/
@Override
protected Boolean doInBackground(Integer... params) {
validateParams(params);
int count_max = params[0];
for (int i = 0; i < count_max; i++) {
int progressPercent = calculateProgressPercent(i, count_max);
publishProgress(progressPercent);
Log.i(TAG, "Counter: " + Integer.toString(i));
Log.i(TAG, "Progress published: " + Integer.toString(progressPercent) + "%");
if (sleep() == false) {
return false;
}
if (doesFail(PROBABILITY_TO_FAIL_EVERY_STEP)) {
Log.i(TAG, "Background fails.");
return false;
}
}
Log.i(TAG, "Background succeeds.");
return true;
}
@Override
protected void onCancelled() {
super.onCancelled();
Log.i(TAG, "Background cancelled.");
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialog.dismiss();
String message = null;
if (result)
message = "Background succeeded.";
else
message = "Background failed.";
Log.i(TAG, message);
createAlertDialog(message).show();
}
private Dialog createAlertDialog(String message) {
AlertDialog.Builder builder = new Builder(progressDialog.getContext());
AlertDialog dialog = builder.setMessage(message).setTitle("Result").setCancelable(true).create();
return dialog;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setProgress(values[0]);
}
/**
* Helper method to decide if the task fails in this step.
*
* @param probabilityToFail
* Value 0..100 the probability to fail.
* @return true if it fails, false if not
*/
private boolean doesFail(int probabilityToFail) {
int prob = random.nextInt(100);
if (prob < probabilityToFail)
return true;
else
return false;
}
/**
* The thread sleeps from step to step to simulate a time consuming task.
*
* @return
*/
private boolean sleep() {
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
return false;
}
return true;
}
private int calculateProgressPercent(int done, int max) {
done = done * 100;
return done / max;
}
private void validateParams(Integer... integers) {
if (integers == null || integers.length != 1 || integers[0] < 0)
throw new IllegalArgumentException();
}
}MainActivity.java:
package my.application;
import my.tasks.CounterTask;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener, OnCancelListener {
private CounterTask counterTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
int id = view.getId();
switch (id) {
case R.id.startButton:
ProgressDialog progressDialog = createProgressDialog();
progressDialog.show();
CounterTask ct = new CounterTask(progressDialog);
counterTask = (CounterTask) ct.execute(100);
break;
default:
break;
}
}
private ProgressDialog createProgressDialog() {
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setProgress(0);
progressDialog.setMax(100);
progressDialog.setTitle("Progress");
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
return progressDialog;
}
@Override
public void onCancel(DialogInterface arg0) {
counterTask.cancel(true);
}
}发布于 2012-05-15 00:12:16
看起来不错。您可以将progressDialog创建并显示在onPreExecute:http://developer.android.com/reference/android/os/AsyncTask.html#onPreExecute()http://developer.android.com/reference/android/os/AsyncTask.html#onPreExecute()中。它将在UI线程中运行,并封装更多的对话逻辑。
你可以在这里删掉几行
String message = null;
if (result)
message = "Background succeeded.";
else
message = "Background failed.";变成了
String message = result ? "Background succeeded." : "Background failed";发布于 2014-04-01 07:38:25
条件运算符可用于改进以下方法:
private boolean doesFail(int probabilityToFail) {
int prob = random.nextInt(100);
if (prob < probabilityToFail)
return true;
else
return false;
}可以改进为
private boolean doesFail(int probabilityToFail) {
return (random.nextInt(100) < probabilityToFail);
}发布于 2015-07-02 09:30:36
定义接口:
public interface AsyncTaskResultListener<T> {
/** notifies Activity when task is done.
* @return true if result parsed OK
* other way false to repeat with RepeatTask()*/
boolean onTaskComplete(T result);
void repeatTask();
}在异步任务中:
AsyncTaskResultListener<T> _callback;
Context _context;
MyAsyncTask(Context context) {
/** check for valid context */
if(Activity.class.isAssignableFrom(context.getClass()) {
_contex = context;
/** check for valid callback */
if(AsyncTaskResultListener.class.isAssignableFrom(context.getClass()) {
/** cast it to interface */
_callback = (AsyncTaskResultListener<T>) context;
}
}
}
@Override
protected void onPostExecute(T result) {
if(_callback!=null) {
if(!callback.onTaskComplete(result) {
/** repeat task */
callback.repeatTask()
}
}
/** dismiss pd */
}在活动中:
public MyActivity exrtends Activity implements AsyncTaskResultListener<T> {
@Override
boolean onTaskComplete(T result) {
/** do work with your result
if satisfied return true, to repeat task return false */
return true;
}
@Override
public void repeatTask() {
/** free to make decision what to do */
}
}我没有什么要指出的,但我的手已经够多了
https://codereview.stackexchange.com/questions/11730
复制相似问题