簡體   English   中英

Android 定時器/定時器任務導致我的應用程序崩潰?

[英]Android timer/timertask causing my app to crash?

只需在我的 mainActivity 的 onCreate 中測試一個簡單的代碼塊:

Timer timer2 = new Timer(); 
        TimerTask testing = new TimerTask() {
            public void run() { 
                Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();

            }
        };
        timer2.schedule(testing, 1000);

我得到了“強制關閉”錯誤。

是什么賦予了?

好吧,對於遇到此問題的其他人,我通過使用 Handler 和 Runnable 來解決問題,這似乎是 UI 交互所必需的:

    final Handler handler = new Handler(); 
    Timer timer2 = new Timer(); 
    TimerTask testing = new TimerTask() {
        public void run() { 
            handler.post(new Runnable() {
                public void run() {
                    Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();
                }

            });


        }
    };
    timer2.schedule(testing, 1000);

我仍然不明白為什么這是必要的,也許有人可以解釋一下? 但是,嘿,至少這段代碼有效,哈哈。

計時器(任務)不好:按照 Android 方式進行。 使用處理程序。

正如您在代碼片段中看到的那樣,go 也很容易:

首先我們需要一個在 100ms 后啟動 Runnable 的 Handler

private Handler handler = new Handler();
handler.postDelayed(runnable, 100);

我們還需要 Handler 的 Runnable

private Runnable runnable = new Runnable() {
   @Override
   public void run() {
      /* do what you need to do */
      foobar();
      /* and here comes the "trick" */
      handler.postDelayed(this, 100);
   }
};

所以“訣竅”是在最后告訴處理程序再次啟動 Runnable。 這樣,runnable 每 100 毫秒啟動一次,就像 scheduleAtFixedRate() TimerTask,如果你想讓它停止,你可以調用handler.removeCallback(runnable)它不會再次啟動,直到你告訴它

應用程序崩潰是因為您試圖從不同的線程(計時器線程)訪問 UI 線程(吐司)的元素。 你不能做這個!

您可以通過以下任一方式繞過它:

從計時器線程向 UI 線程發送處理程序消息,然后在 UI 處理程序 function 中顯示 toast。

或者

在計時器代碼運行中使用“runOnUiThread”:

@Override

public void run() 

{

    mainActivity.runOnUiThread(new Runnable() {

        public void run() {

            // Access/update UI here

            Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();

        }

    });

}

@YoungMoney

它有效,但只是第一次......你讓它每秒顯示 Toast 消息嗎?

我的只工作過一次...

===

編輯:剛剛意識到您的最后一行代碼缺少最后一個值,即重復頻率。

對於其他有關人員,請更改以下內容:

timer2.schedule(testing, 1000);

對此:

timer2.schedule(testing, 1000, 2000);

如果你想在 1 秒內啟動計時器,並且每 2 秒更新一次。

TimerTask task = new TimerTask() {
    @Override
    public void run() {
        //do something

    }
};

Timer t = new Timer();
t.schedule(task, 2000);

暫無
暫無

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

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