如何在Android中停止Handler

15

我在我的应用程序中使用GridView创建了一个日历,其中我使用ImageView显示日期和一些事件的可用性,并为此创建了一个处理程序。

现在我想停止这个处理程序。

MainActivity.java

// inside oncreate

Handler handler = new Handler();
refreshCalendar();

// outside oncreate

public void refreshCalendar() { 
    calAdapter.refreshDays();
    calAdapter.notifyDataSetChanged();
    handler.post(calendarUpdater);
    calTitle.setText(android.text.format.DateFormat.format("MMMM yyyy", cal));
}
public Runnable calendarUpdater = new Runnable() {

    @Override
    public void run() {
        items.clear();
        allData = new ArrayList<HashMap<String,String>>();
        allData.clear();
        allData = db.showAllEvents();

        String currentDate = (String)android.text.format.DateFormat.format("MM/yyyy", cal);
        for(int i=0; i<allData.size(); i++)
        {
            String date[] = allData.get(i).get("date").split("/");
            String md[] = currentDate.split("/");
            if(date[1].equals(md[0]) && date[2].equals(md[1]))
            {
                items.add(date[0]);
                System.out.println("dates: "+date[0]);
            }
        }
        calAdapter.setItems(items);
        calAdapter.notifyDataSetChanged();
    }
};
请告诉我应该如何在哪里禁用这个线程。
5个回答

26
您可以使用此方法停止该可运行程序。
handler.removeCallbacks(calendarUpdater);

removeCallbacks(Runnable r) :移除消息队列中所有等待执行的Runnable r

Edit

你可以按照以下方式组织你的代码

MainActivity.javaonCreate()方法中:

Handler handler = new Handler();
refreshCalendar()

//outside  oncreate 

public void refreshCalendar() { 
    calAdapter.refreshDays();
    calAdapter.notifyDataSetChanged();
    startRepeatingTask();
    calTitle.setText(android.text.format.DateFormat.format("MMMM yyyy", cal));
}

public Runnable calendarUpdater = new Runnable() {

    @Override
    public void run() {
        items.clear();
        allData = new ArrayList<HashMap<String,String>>();
        allData.clear();
        allData = db.showAllEvents();

        String currentDate = (String)android.text.format.DateFormat.format("MM/yyyy", cal);
        for(int i=0; i<allData.size(); i++)
        {
            String date[] = allData.get(i).get("date").split("/");
            String md[] = currentDate.split("/");
            if(date[1].equals(md[0]) && date[2].equals(md[1]))
            {
                items.add(date[0]);
                System.out.println("dates: "+date[0]);
            }
        }
        calAdapter.setItems(items);
        calAdapter.notifyDataSetChanged();
        handler.postDelayed(calendarUpdater,5000); // 5 seconds
    }
};

void startRepeatingTask()
{
    calendarUpdater.run(); 
}

void stopRepeatingTask()
{
    handler.removeCallbacks(calendarUpdater);
}

现在您只需调用startRepeatingTask()来发布消息并停止使用stopRepeatingTask()

继承自以下链接

如何延迟一段时间后重复执行任务?


1
把这段代码放在哪里?当我把这段代码放在 handler.post() 之后时,它甚至不会启动。 - Abhishek Dhiman
我可以“移除”正在运行的Runnable吗? - Minh Nghĩa

12
尝试以下代码行:

handler.removeMessages(0);

移除消息队列中,所有带有代码what的待处理消息。


9

Handler没有需要被停止或启动的内容。它只是一个将消息和Runnable发布到线程队列的网关。在你的情况下,你正在发布一个Runnable,这个Runnable将在Handler的线程上运行。你必须停止这个Runnable。所以,在那个for循环里放一个检查来终止它。

你也可以使用removeCallbacks(Runnable r)Handler上取消发布的Runnable。但这不会删除那些已经在运行的Runnable


2
你可以尝试使用 onStop() 方法:

handler.removeCallbacksAndMessages(calendarUpdater);

1
评论质量答案。 - Mathews Sunny

1
将handler作为一个字段。然后在您的活动中,覆盖onStop方法并停止处理程序回调消息,如下所示:
@Override
    protected void onStop() {
        super.onStop();
        handler.removeCallbacks(calendarUpdater);
    }

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