从服务器返回响应时完成活动,但等待动画结束

时间:2014-06-29 14:15:45

标签: android android-activity android-animation

我通过Volley向服务器发送请求;发送后,增加一个显示请求数的变量。

VolleyGeneral.getInstance().addToRequestQueue(jsonObj,TAG);
numberOfReq++;

然后当我收到回复时,减少该变量。

@Override
public void onResponse(JSONObject response){
    numberOfReq--;
}

另一方面,我正在显示一个图像,使用淡入淡出动画2秒然后我完成了活动并转到下一个活动。

但我想在完成活动之前等待所有服务器响应。所以我这样写这个部分:

@Override
public void onAnimationEnd(Animation anim){
    while(numberOfReq == 0){
        numberOfReq = -1;
        startActivity(intent);
        finish();
        break;
    }
}

如果服务器在2秒之前发送响应,则一切都是Okey。

如果在2秒后收到回复,则活动无法完成。

5 个答案:

答案 0 :(得分:3)

你知道Volley创建并维护多个线程,对吗?

增量/减量不是线程安全操作。而是使用类似的东西:

AtomicInteger numberOfReq = new AtomicInteger(0);

numberOfReq.incrementAndGet(); // ++

numberOfReq.decrementAndGet(); // --

不确定这是导致问题的原因,但如果不是这样的事件 - 这是一个等待发生的错误。

编辑:

将numberOfReq设置为volatile int将无法解决问题。

挥发性不保证原子性。它只保证下一个 读取变量的线程将在执行操作后看到其确切的值 通过先前的线程。

现在,增量(和减量)操作实际上是一个三元组:

a = x;
b = a + 1;
x = b;

如果此计算不强制原子性,例如通过使用AtomicInteger, 没有什么会阻止另一个线程在这样的计算过程中访问一个易变的字段,并且基本上取消了进程中的增量。

答案 1 :(得分:3)

也许我不理解这个问题,因为答案似乎非常简单。只要活动是"准备完成",就设置一个标志,然后在onResponse()中检查这个条件。

onAnimationEnd()或最后onResponse()将首先运行,第二个应该开始第二个活动。例如:

private boolean mReadyToProceed;

@Override
public void onAnimationEnd(Animation anim)
{
    if (numberOfReq == 0)
        startOtherActivityAndFinish();
    else
       mReadyToProceed = true;
}

@Override
public void onResponse(JSONObject response)
{
    numberOfReq--;
    if (mReadyToProceed && numberOfReq == 0)
        startOtherActivityAndFinish();
}

(注意:确保减量和比较不受其他请求线程的影响,可能使用锁定或使用AtomicInteger)。

答案 2 :(得分:0)

正如matiash所说,你可以在onResponse()上设置一个标志,并可以检查该值以获得所需的结果,或者你可以使用广播接收器,这也是一个有效的解决方案

答案 3 :(得分:0)

为什么不以两种方式进行检查,而不是一种方式

如果在您制作动画时响应已到,则 onAnimationEnd()必须负责关闭并启动新活动

否则反过来(图像动画在响应之前结束) onResponse()必须负责执行活动结束和新活动。

Ps:关于线程安全变量@matiash似乎已经抛出了足够的光线

答案 4 :(得分:0)

您应该将启动其他活动的方法分开。像这样:

private boolean animationEnded = false;    

@Override
public void onResponse(JSONObject response){
    numberOfReq--;
    checkStartOtherActivity();
}

@Override
public void onAnimationEnd(Animation anim){
    animationEnded = true;
    checkStartOtherActivity();
}

public void checkStartOtherActivity(){
    if (numberOfReq == 0 && animationEnded){
         startActivity(intent);
         finish();
    }
}