簡體   English   中英

如何關閉主UI線程運行TimerTask?

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

我遇到了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



}

}

您可以使用HandlerThread來在單獨的線程上運行Handler

文檔:

 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

        }
    });

該處理程序正在主ui線程中運行和處理,因此doUpdateTimeout方法將在主線程中執行。

在您的代碼中,運行10秒鍾后, timeTickDown等於0,並且代碼timerHandler.post(doUpdateTimeout); 將被調用,它將在主線程中執行。 因為它只是讓timeTickDown = 2; 一秒鍾后,此代碼將再次執行(在主ui線程中),然后每秒執行一次。如果doUpdateTimeoutupdateTimeout還有其他代碼,則您的主線程會很慢。

只需更改timerHandler.post(doUpdateTimeout); updateTimeout() (直接調用它,然后在Timer線程而不是主ui線程中執行)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM