Handler.postDelayed导致滞后

时间:2015-09-07 13:17:52

标签: java android performance android-handler

我创建了一个可以使用我们的SIP服务器调用的应用程序。现在我要做的是向用户显示他的通话时间。我的脚本实际上正在工作,但我注意到调用时间越长,我的应用程序变得越来越迟钝。这是我的代码片段

Handler h = new Handler(Looper.getMainLooper());
_isOnCall = true;
long time = 0;
int x = 0;

while(_isOnCall) {
     if (_isOnCall){
         final int counter = 1 + x;
         time += 1000;
         h.postDelayed(new Runnable() {
             @Override
             public void run() {
                 (TargetDetailsActivity.this).runOnUiThread(new Runnable() {
                     @Override
                     public void run() {
                         final int seconds = counter % 60;
                         final int minutes = (counter % 3600) / 60;
                         final int hours = counter / 3600;

                         callcounter.post(new Runnable() {
                             @Override
                             public void run() {
                                 callcounter.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
                             }
                         });
                     }
                 });
             }
         }, time);
         x++;
     }else{
         break;
     }
}

基本上代码所做的只是计算他在电话上的秒/分钟/小时。当他挂断电话时,我会拨打下面的代码:

_isOnCall = false;
h.removeCallbacksAndMessages(null);

我不确定导致滞后的原因。救命!感谢。

更新

我能够通过使用Timer的建议来实现这一点。这是我的代码供将来参考:

private Timer myTimer;
private int counter_time=0;

public void onCallEstablished() {
    myTimer = new Timer();
    myTimer.schedule(new TimerTask() {
        @Override
        public void run() {
            TimerMethod();
        }

    }, 0, 1000);
}

private void TimerMethod()
{
    this.runOnUiThread(Timer_Tick);
}

private Runnable Timer_Tick = new Runnable() {
    public void run() {
        counter_time++;
        int seconds = counter_time % 60;
        int minutes = (counter_time % 3600) / 60;
        int hours = counter_time / 3600;

        callcounter.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
    }
};


public void releaseCall(){

    if(myTimer != null){
        myTimer.cancel();
        myTimer.purge();
        counter_time = 0;
    }
}

1 个答案:

答案 0 :(得分:0)

看起来每个Runnable都会保存对其父对象的引用,在这种情况下是一个嵌套的Runnable。尝试使用堆快照来检测内存问题,看看是否是这种情况。

您还可以使用时间间隔进行重复任务,并在通话结束时停止循环。

Timer timer = new Timer();
TimerTask myTask = new TimerTask() {
    @Override
    public void run() {
        // whatever you need to do every 2 seconds
    }
};

timer.scheduleAtFixedRate(myTask,
                       firstTime,
                       period);

有关计时器的更多信息,您可以查看docs