在操作网络请求的时候,我们一般在start的时候我们会showProgress,然后在请求完成的时候dismissProgress,这样可以保证同步请求数据。但是我们一般还会遇到这样的情况,需要一次请求两个接口,请求完第一个接口之后操作UI,然后再请求另一个接口,这两个接口要同步进行,如果我们还按照前面的方法来操作进度条就会出现连续两个进度条显示的情况,所以写了一个分步处理任务的方法。
首先是步骤轴/事件轴类
import java.util.concurrent.TimeUnit;
import android.text.TextUtils;
/**
* 步骤轴,事件轴,用于记录同步状态下不同步骤的运行情况
*
*
*/
public class StepLine {
/**
* 重复步骤最小间隔定义(ms)
*/
private static final int MIN_REPEAT_INTERVAL = 500;
/**
* 最后一次步骤的标识/时间戳(ns)
*/
private String mLastStep = null;
private long mLastStepTimeStamp = 0;
/**
* stepline创建器
*
*/
private static class StepHolder {
public static StepLine instance = new StepLine();
}
public static StepLine getInstance() {
return StepHolder.instance;
}
private StepLine() {
}
/**
* 向步骤轴添加一个步骤
*
* @return true - 添加步骤成功并记录时间; false - 由于重复等原因添加失败
*/
public synchronized boolean add(String step) {
// 纳秒
long currTime = System.nanoTime();
if (!TextUtils.isEmpty(mLastStep) && mLastStep.equals(step)) {
if (currTime - mLastStepTimeStamp <= TimeUnit.MILLISECONDS
.toNanos(MIN_REPEAT_INTERVAL)) {
return false;
}
}
mLastStep = step;
mLastStepTimeStamp = currTime;
return true;
}
}
然后是分步处理任务类,因为遇到情况所限,最多支持3步处理
import android.text.TextUtils;
/**
* 分步处理的任务 最多支持3步处理
*
*
*/
public abstract class StepTask {
/**
* 步骤数量
*/
private int mStepCount = 0;
/**
* 当前步骤(1为起始值)
*/
private int mCurrStep = 1;
/**
* 在完成的时候需要执行下一个步骤
*/
private boolean mExecuteNext = false;
/**
* 任务名称
*/
private String mTaskName = null;
/**
* 任务开始
*
*/
protected abstract boolean onStart();
/**
* 任务完成
*
*/
protected abstract void onFinish();
/**
* 步骤1
*/
protected abstract void onStep1Start();
/**
* 步骤2
*/
protected abstract void onStep2Start();
/**
* 步骤3
*/
protected void onStep3Start() {
}
/**
* constructor
*
* @param stepCount
* 步骤数量
*/
public StepTask() {
init(2);
}
/**
* constructor
*
* @param taskName
* 任务名称
*/
public StepTask(String taskName) {
init(2);
mTaskName = taskName;
}
/**
* constructor
*
* @param stepCount
* 步骤数量
*/
public StepTask(int stepCount) {
init(stepCount);
}
/**
* constructor
*
* @param taskName
* 任务名称
* @param stepCount
* 步骤数量
*/
public StepTask(int stepCount, String taskName) {
init(stepCount);
mTaskName = taskName;
}
/**
* 初始化方法
*
* @param stepCount
*/
private void init(int stepCount) {
if (stepCount > 3) {
throw new IllegalArgumentException(
"The count of step must be less than or equal 3.");
}
mStepCount = stepCount;
mCurrStep = 1;
if (TextUtils.isEmpty(mTaskName)) {
// 外部没有设置任务名,使用默认
mTaskName = StepTask.class.getCanonicalName();
}
}
/**
* 下一个步骤
*/
public void nextStep() {
mExecuteNext = true;
}
/**
* 步骤结束
*/
public void finishStep() {
if (!mExecuteNext) {
finish();
return;
}
if (mCurrStep >= mStepCount) {
finish();
return;
}
mCurrStep++;
mExecuteNext = false;
switch (mCurrStep) {
case 1:
onStep1Start();
break;
case 2:
onStep2Start();
break;
case 3:
onStep3Start();
break;
default:
finish();
break;
}
}
/**
* 开始执行
*/
public void execute() {
// 确认步骤不重复
if (!StepLine.getInstance().add(mTaskName)) {
return;
}
if (!onStart()) {
finish();
return;
}
onStep1Start();
}
/**
* 结束所有步骤
*/
private void finish() {
// 清空步骤轴
StepLine.getInstance().add("");
onFinish();
}
}
实际应用中可以这么写:
new StepTask() {
@Override
protected boolean onStart() {
if (!checkNetWork || !showProgress()) {
// 没有网或者没有显示进度条
return false;
}
return true;
}
@Override
protected void onFinish() {
dismissProgress();// 隐藏进度条
}
@Override
protected void onStep1Start() {
// 第一步开始,操作第一步,成功之后可以操作UI,如果要进行第二步,调用nextStep就可以,结束的时候调用finishStep
// 如果不调用nextStep和finishStep就不会进行第二步了
}
@Override
protected void onStep2Start() {
// 第二步开始,操作成功后如果要调用第三步就和上面一样,然后复写onStep3Start,结束的时候调用finishStep
}
}.execute();
这样,两次网络请求就只会出现一次进度条,并且还可以通过Handler来操作UI,第一次请求成功了,后面的UI就可以更新。增强了应用的用户体验。