处理程序在调用 removeCallbacksAndMessages(null) 后不会结束
Handlers don't end after calling removeCallbacksAndMessages(null)
我有两个处理程序。处理程序中的处理程序。他们都在一个for循环中。
概览是这样的,
for{
handler.postDelayed(runnableA{
for{
handler2.postDelayed(runnableB{
function();
}, 3000);
}
}, 1000);
}
我想在用户单击 back button
时随时结束处理程序的工作。所以,我创建了两个 Runnable 类 这样我就可以使用 runnableA.removellbacksAndMessages(null)
.
Handler messageHandler;
Handler countDownHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Start Play in 5 seconds", Toast.LENGTH_SHORT).show();
countDownHandler = new Handler();
for (int i = 7; i >= 0; --i) {
final int idx = i;
Runnable countRunnable = new CountRunnable(idx, countDownView);
countDownHandler.postDelayed(countRunnable, 1000 * (7 - i));
}
}
这是 Runnable 类。
public class CountRunnable implements Runnable {
int idx;
TextView countDownView;
public CountRunnable(int idx, TextView countDownView) {
this.idx = idx;
this.countDownView = countDownView;
}
@Override
public void run() {
int messageSize = messageItems.size();
for (int j = 0; j < messageSize; j++) {
final int jdx = j;
messageHandler = new Handler();
Runnable messageRunnable = new MessageRunnable(jdx);
messageHandler.postDelayed(messageRunnable, 3000 * jdx);
}
}
}
class MessageRunnable implements Runnable {
int jdx;
public MessageRunnable(int jdx) {
this.jdx = jdx;
}
@Override
public void run() {
addMessageView(messageItems.get(jdx));
}
}
这是onBackPressed()
:
@Override
public void onBackPressed() {
super.onBackPressed();
Toast.makeText(getApplicationContext(), "All Work Ended.", Toast.LENGTH_SHORT).show();
scrollFlag = true;
try {
messageHandler.removeCallbacksAndMessages(null);
} catch (Exception e) {
Log.d(TAG, "messageHandler never used");
e.printStackTrace();
}
try {
countDownHandler.removeCallbacksAndMessages(null);
} catch (Exception e) {
e.printStackTrace();
}
}
public void addMessageView(String message){
try{
mTextView.setText(message);
}catch(Exception e){
Toast.makeText(getApplicationContext(), "Abnormal End", Toast.LENGTH_SHORT).show();
}
}
但是,我不断收到错误消息,因为 activity 已经结束,但处理程序找不到 activity。因此,Abnormal End
Toast 消息显示与内部 for 循环的大小一样多。
如果我不使用 Toast 消息,我可以忽略它,但我担心内存泄漏或 Bad formed Program 或类似的东西。
我该如何解决这个问题?
主要问题是您正在创建 n
个 CountRunnable
和 m
个 MessageRunnables
。尽管创建了多个处理程序,但您只删除了最新创建的 Hanlder
.
的回调
这是你应该做的:
保留所有 Handler
和 Runnables
的引用,并对所有这些调用 messageHandler.removeCallbacksAndMessages(null);
和 countDownHandler.removeCallbacksAndMessages(null);
。
我有两个处理程序。处理程序中的处理程序。他们都在一个for循环中。
概览是这样的,
for{
handler.postDelayed(runnableA{
for{
handler2.postDelayed(runnableB{
function();
}, 3000);
}
}, 1000);
}
我想在用户单击 back button
时随时结束处理程序的工作。所以,我创建了两个 Runnable 类 这样我就可以使用 runnableA.removellbacksAndMessages(null)
.
Handler messageHandler;
Handler countDownHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Start Play in 5 seconds", Toast.LENGTH_SHORT).show();
countDownHandler = new Handler();
for (int i = 7; i >= 0; --i) {
final int idx = i;
Runnable countRunnable = new CountRunnable(idx, countDownView);
countDownHandler.postDelayed(countRunnable, 1000 * (7 - i));
}
}
这是 Runnable 类。
public class CountRunnable implements Runnable {
int idx;
TextView countDownView;
public CountRunnable(int idx, TextView countDownView) {
this.idx = idx;
this.countDownView = countDownView;
}
@Override
public void run() {
int messageSize = messageItems.size();
for (int j = 0; j < messageSize; j++) {
final int jdx = j;
messageHandler = new Handler();
Runnable messageRunnable = new MessageRunnable(jdx);
messageHandler.postDelayed(messageRunnable, 3000 * jdx);
}
}
}
class MessageRunnable implements Runnable {
int jdx;
public MessageRunnable(int jdx) {
this.jdx = jdx;
}
@Override
public void run() {
addMessageView(messageItems.get(jdx));
}
}
这是onBackPressed()
:
@Override
public void onBackPressed() {
super.onBackPressed();
Toast.makeText(getApplicationContext(), "All Work Ended.", Toast.LENGTH_SHORT).show();
scrollFlag = true;
try {
messageHandler.removeCallbacksAndMessages(null);
} catch (Exception e) {
Log.d(TAG, "messageHandler never used");
e.printStackTrace();
}
try {
countDownHandler.removeCallbacksAndMessages(null);
} catch (Exception e) {
e.printStackTrace();
}
}
public void addMessageView(String message){
try{
mTextView.setText(message);
}catch(Exception e){
Toast.makeText(getApplicationContext(), "Abnormal End", Toast.LENGTH_SHORT).show();
}
}
但是,我不断收到错误消息,因为 activity 已经结束,但处理程序找不到 activity。因此,Abnormal End
Toast 消息显示与内部 for 循环的大小一样多。
如果我不使用 Toast 消息,我可以忽略它,但我担心内存泄漏或 Bad formed Program 或类似的东西。
我该如何解决这个问题?
主要问题是您正在创建 n
个 CountRunnable
和 m
个 MessageRunnables
。尽管创建了多个处理程序,但您只删除了最新创建的 Hanlder
.
这是你应该做的:
保留所有 Handler
和 Runnables
的引用,并对所有这些调用 messageHandler.removeCallbacksAndMessages(null);
和 countDownHandler.removeCallbacksAndMessages(null);
。