如何在主UI线程上运行TimerTask?

时间:2014-06-13 03:21:54

标签: java android multithreading

我遇到了使用In App Purchasing(异步任务)的TimerTask干扰问题。 我对Threads很弱,所以我相信它在主UI线程上运行,占用资源。 我怎样才能在UI线程外运行它?我搜索过,并尝试使用处理程序的一些建议。但似乎我得到相同的结果,应用程序变得非常滞后。 当我不运行此任务(刷新每500毫秒)时,活动运行顺畅,并且在应用内购买期间没有挂起。 感谢您的帮助,以下代码段:

公共类DummyButtonClickerActivity扩展了Activity {

        protected Timer timeTicker = new Timer("Ticker");
        private Handler timerHandler = new Handler();
        protected int timeTickDown = 20;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mainhd);

    // start money earned timer handler
    TimerTask tick = new TimerTask() {
        public void run() {
            myTickTask();
        }
    }; 

    timeTicker.scheduleAtFixedRate(tick, 0, 500); // 500 ms each


} // End OnCreate



protected void myTickTask() {

    if (timeTickDown == 0) {

        /// run my code here
        //total = total + _Rate;





        timerHandler.post(doUpdateTimeout);
}
      else if(timeTickDown < 0) {
        // do nothing
    }

    timeTickDown--;

}

private Runnable doUpdateTimeout = new Runnable() {
    public void run() {

        updateTimeout();
    }
};



private void updateTimeout() {

    // reset tick
    timeTickDown = 2; // 2* 500ms == once a second



}

}

2 个答案:

答案 0 :(得分:1)

您可以使用将在单独的线程上运行处理程序的HandlerThread

<强>文件:

 Handy class for starting a new thread that has a looper.
 The looper can then be used to create handler classes. Note that start() must still be called.

示例:

     HandlerThread mHandlerThread = new HandlerThread("my-handler");
     mHandlerThread.start();
     Handler mHandler = new Handler(mHandlerThread.getLooper());

更新

 private Runnable doUpdateTimeout;
private HandlerThread mHandlerThread;
private Handler timerHandler;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mainhd);

    // start money earned timer handler
    TimerTask tick = new TimerTask() {
        public void run() {
            myTickTask();
        }
    }; 

    mHandlerThread = new HandlerThread("my-handler");
    mHandlerThread.start();

    timerHandler = new Handler(mHandlerThread.getLooper());
    doUpdateTimeout = new Runnable() {
        public void run() {

            updateTimeout();
        }
    };

    timeTicker.scheduleAtFixedRate(tick, 0, 500); // 500 ms each


} // End OnCreate



protected void myTickTask() {

    if (timeTickDown == 0) {

        /// run my code here
        //total = total + _Rate;

        timerHandler.post(doUpdateTimeout);
}
      else if(timeTickDown < 0) {
        // do nothing
    }

    timeTickDown--;

}





private void updateTimeout() {

    // reset tick
    timeTickDown = 2; // 2* 500ms == once a second

}
}

当您想要从不同的线程

更新TextView时

请致电:

YOU_ACITIVITY_CLASS.this.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            //update here

        }
    });

答案 1 :(得分:0)

处理程序在主ui线程中运行和处理,因此方法doUpdateTimeout将在主线程中执行。

在你的代码中,运行10秒后,timeTickDown等于0,代码timerHandler.post(doUpdateTimeout);将被调用,这将在主线程中执行。因为它只是让timeTickDown = 2;一秒钟后,这个代码将再次执行(在主ui线程中)然后继续执行。如果doUpdateTimeout或{{1}中有其他代码你的主线程将是滞后的。

只需将updateTimeout更改为timerHandler.post(doUpdateTimeout);(直接调用它,然后在updateTimeout()线程中执行,而不是主ui线程。)