简体   繁体   English

如何关闭主UI线程运行TimerTask?

[英]how to run TimerTask off main UI thread?

I am having trouble with a TimerTask Interfering with In App Purchasing (Async Tasks). 我遇到了TimerTask干扰应用程序内购买(异步任务)的麻烦。 I am weak with Threads, so I believe it is running on the main UI thread, eating up resources. 我对Threads很虚弱,所以我认为它在主UI线程上运行,占用了资源。 How can I run this outside the UI thread? 我如何在UI线程之外运行它? I have searched, and tried some suggestions using handlers. 我进行了搜索,并尝试使用处理程序提出了一些建议。 but seems like I get the same result, app gets really laggy. 但似乎我得到了相同的结果,应用程序真的很滞后。 when I don't run this task (refreshes every 500mS), the activity runs smoothly, and there are no hangs during In app purchases. 当我不执行此任务(每500毫秒刷新一次)时,活动会顺利进行,并且在应用内购买过程中不会出现挂起的情况。 Your help is appreciated, code snippet below: 感谢您的帮助,下面的代码段:

public class DummyButtonClickerActivity extends Activity { 公共类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



}

} }

You can use HandlerThread that will run your Handler on a separate Thread 您可以使用HandlerThread来在单独的线程上运行Handler

documentation: 文档:

 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.

example: 例:

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

update: 更新:

 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

}
}

when you want to update the TextView from different thread 当您想从其他线程更新TextView时

call this: 称之为:

YOU_ACITIVITY_CLASS.this.runOnUiThread(new Runnable() {

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

        }
    });

The handler is running and processing in the main ui thread,so the method doUpdateTimeout will be executed in the main thread. 该处理程序正在主ui线程中运行和处理,因此doUpdateTimeout方法将在主线程中执行。

In your code, after running 10 seconds later,the timeTickDown equals to 0 and code timerHandler.post(doUpdateTimeout); 在您的代码中,运行10秒钟后, timeTickDown等于0,并且代码timerHandler.post(doUpdateTimeout); will be invoked,which will be executed in the main thread. 将被调用,它将在主线程中执行。 Because it just let timeTickDown = 2; 因为它只是让timeTickDown = 2; one second later,this code will be executed again(in the main ui thread) and then go on in each second.If there is some other code in doUpdateTimeout or updateTimeout ,your main thread will be laggy. 一秒钟后,此代码将再次执行(在主ui线程中),然后每秒执行一次。如果doUpdateTimeoutupdateTimeout还有其他代码,则您的主线程会很慢。

Just change timerHandler.post(doUpdateTimeout); 只需更改timerHandler.post(doUpdateTimeout); to updateTimeout() (call it directly and then execute it in the Timer thread,not the main ui thread). updateTimeout() (直接调用它,然后在Timer线程而不是主ui线程中执行)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM