安卓处理程序调用Runnable两次

3
我知道这个问题已经被问过了,但没有提供答案。我也尝试在其他地方寻找答案,跟踪函数调用并检查一切,但我无法找到答案。 我有一个非常简单的Handler,在每秒钟调用一个Runnable变量。它的目的是跟踪活动上花费的时间。
因此,处理程序在onCreate中开始调用,并且在Runnable中有一个postDelayed(runnableVar, 1000),以继续每秒运行一次。这会更新活动中的文本视图。
文本视图显示所有内容都为双倍。我检查了我的日志,并发现Runnable被调用了两次。我不知道为什么会发生这种情况。以下是我的代码:
//My runnable variable in the activity
private Runnable mUpdateTimeTask = new Runnable(){
    @Override
    public void run(){
         if (gameTimer != null) {
             Log.d("UPDATERUNNABLE", "Inside runnable run");
               gameTimer.setText(getTime());
           }
        mHandler.postDelayed(this,1000);
    }
};

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    Log.d(TRIALTAG,"Inside on create");
            startMins = mPrefsMin;      //This is set in onPause and retrieved onResume
    startSecs = mPrefsSecs;
            Log.d(TRIALTAG,"Start mins : " + startMins + " Start Secs : " + startSecs);
    mHandler.removeCallbacks(mUpdateTimeTask);
    mHandler.post(mUpdateTimeTask); 
    }

private String getTime() {
     String finalTime;
     Log.d("GETTIME", "Start secs is : " + startSecs);
     if(startSecs >= 60){
         startSecs=0;
         startMins++;
     }
     if(startSecs<10){
         finalTime = startMins+":0"+startSecs;
     }else{
         finalTime = startMins+":"+startSecs;
     }
        startSecs++; 
        return finalTime;
    }

 @Override
protected void onPause(){
    super.onPause();
    Log.d(TRIALTAG,"On Pause CALLED");
    mHandler.removeCallbacks(mUpdateTimeTask);
    SharedPreferences.Editor ed = mPrefs.edit();
    ed.putInt("my_mins", startMins);
    ed.putInt("my_secs", startSecs);
    ed.commit();
}

@Override
protected void onResume(){
    super.onResume();
    Log.d(TRIALTAG,"On RESUME CALLED");
    if(gameTimer != null){
        mPrefs = getSharedPreferences("mPrefs", MODE_PRIVATE);
        mPrefsMin = mPrefs.getInt("my_mins", 0);
        mPrefsSecs = mPrefs.getInt("my_secs", 0);
        mHandler.post(mUpdateTimeTask);
    }else{
        mPrefsMin = 0;
        mPrefsSecs = 0;
    }
}

这一切都在我的活动类中。我做错了什么??
3个回答

3
问题在于您在onCreateonResume方法中都提交了您的Runnable对象。尝试修改onResume方法,并删除先前添加的Runnable
@Override
protected void onResume(){
    super.onResume();
    Log.d(TRIALTAG,"On RESUME CALLED");
    if(gameTimer != null){
        mPrefs = getSharedPreferences("mPrefs", MODE_PRIVATE);
        mPrefsMin = mPrefs.getInt("my_mins", 0);
        mPrefsSecs = mPrefs.getInt("my_secs", 0);
        mHandler.removeCallbacks(mUpdateTimeTask);
        mHandler.post(mUpdateTimeTask);
    }else{
        mPrefsMin = 0;
        mPrefsSecs = 0;
    }
}

非常感谢!感谢你提供的解决方案以及指出我的错误。我还是Android的新手,这些东西对我来说应该更明显,但现在并不是...已接受为答案。 - kvnam
如果您在 onResume 中调用 removeCallbacks,则无需在 onCreate 中发布。 - pskink

0

还有另一种方法,可以在特定时间间隔内更新UI。

new Thread(new Runnable() {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (true) {
                try {
                    Thread.sleep(10000);
                    mHandler.post(new Runnable() {

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            gameTimer.setText(getTime());
                        }
                    });
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }
        }
    }).start();

感谢您提供的解决方案,尽管它并没有直接回答我的问题,但我相信这对将来会有所帮助.. :) - kvnam

0

在 onCreate 中移除

mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.post(mUpdateTimeTask);

感谢您提供的解决方案。不得不先将答案给予vmironov,并且解释原因。 - kvnam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接