如何在不崩溃的情况下中断 onBackPressed 线程?
How to interrupt a thread onBackPressed without crashing?
我已经尝试重写 onBackPressed 以不仅完成当前 activity,而且在我调用下一个 activity 的意图时中断线程。当我之前按下时,启动 activity 完成,但线程保持 运行 并将意图调用到下一个 activity。现在我已经在 BackPressed 上包含了线程中断,当我按回键时应用程序崩溃了。我做错了什么?
skipscreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE);
savestate.edit().putBoolean("skip", true).apply();
skip= true;
homeintent();
}
});
Thread splashthread = new Thread() {
@Override
public void run() {
try {
sleep(3000);
if (!skip) { homeintent();}
} catch (InterruptedException Interrupt) {
Interrupt.printStackTrace();
}
}
};
splashthread.start();
}
private void homeintent() {
Intent i = new Intent(splash.this, home.class);
startActivity(i);
finish();
}
@Override
public void onBackPressed() {
splashthread.interrupt();
finish();
}
}
更新:(此解决方案对我有用)。
skipscreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE);
savestate.edit().putBoolean("skip", true).apply();
skip= true;
homeintent();
}
});
Thread splashthread = new Thread() {
@Override
public void run() {
try {
sleep(3000);
if (!skip) { homeintent();}
} catch (InterruptedException Interrupt) {
Interrupt.printStackTrace();
}
}
};
splashthread.start();
}
private void homeintent() {
if (!ThreadInterrupted) {
Intent i = new Intent(splash.this, home.class);
startActivity(i);
}
finish();
}
@Override
public void onBackPressed() {
SharedPreferences savestate= getSharedPreferences("ThreadInterrupted", MODE_PRIVATE);
savestate.edit().putBoolean("ThreadInterrupted", true).apply();
ThreadInterrupted = true;
homeintent();
}
}
当您在线程上调用 interrupt() 方法时,在睡眠状态下,将抛出 InterruptedException。
你可以在你的线程中检查天气它应该继续:
Thread splashthread = new Thread() {
@Override
public void run() {
while (shouldContinue) {
doSomeWork();
}
}
};
然后您可以在 onBackPressed 方法中将 shouldContinue 更改为 false:
@Override
public void onBackPressed() {
shouldContinue = false;
finish();
}
Udi 我已经回答了你的问题。
但我建议您使用 TimerTask and Timer 而不是 Thread.
Timer timer;
TimerTask timertask;
timer = new Timer();
timertask = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
homeintent();
}
});
}
};
timer.schedule(timertask, 3000);
@Override
public void onBackPressed() {
if(timertask!=null){
timertask.cancel();
}
if(timer!=null){
timer.cancel();
}
finish();
}
您可以创建一个 volatile boolean
检查以阻止线程继续进行,请参见以下代码:
private volatile boolean cancelled = false;
Thread splashthread = new Thread() {
@Override
public void run() {
if ( cancelled ) {
return; // or handle this however you want
}else{
// do what ever you want to do here
}
}
};
splashthread.start();
然后在 onBackPressed
中做这样的事情:
@Override
public void onBackPressed() {
cancelled = true;
finish();
}
建议使用 volatile 关键字,因为通常执行取消的线程不一定与被取消的线程相同。将 boolean
检查标记为 volatile
可确保检查标志的线程将看到最新值。
为了给您一个简洁的答案以及解释将来如何做,请看一下 Handler class and the Handler.postDelayed() 方法。
private Handler homeIntenthandler;
@Override
protected void onCreate(){
//other things
skipscreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE);
savestate.edit().putBoolean("skip", true).apply();
skip= true;
homeintent();
}
});
//initialise handler and set timer;
homeIntenthandler= new Handler();
homeIntenthandler.postDelayed(new Runnable() {
@Override
public void run() {
homeintent();
}
},3000);
}
}
private void homeintent() {
Intent i = new Intent(splash.this, home.class);
startActivity(i);
finish();
}
@Override
public void onBackPressed() {
if(homeIntenthandler!=null)
homeIntenthandler.removeCallbacksAndMessages(null)
finish();
}
}
Handler.removeCallbacksAndMessages(null)
基于为 same
提供的文档
我已经尝试重写 onBackPressed 以不仅完成当前 activity,而且在我调用下一个 activity 的意图时中断线程。当我之前按下时,启动 activity 完成,但线程保持 运行 并将意图调用到下一个 activity。现在我已经在 BackPressed 上包含了线程中断,当我按回键时应用程序崩溃了。我做错了什么?
skipscreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE);
savestate.edit().putBoolean("skip", true).apply();
skip= true;
homeintent();
}
});
Thread splashthread = new Thread() {
@Override
public void run() {
try {
sleep(3000);
if (!skip) { homeintent();}
} catch (InterruptedException Interrupt) {
Interrupt.printStackTrace();
}
}
};
splashthread.start();
}
private void homeintent() {
Intent i = new Intent(splash.this, home.class);
startActivity(i);
finish();
}
@Override
public void onBackPressed() {
splashthread.interrupt();
finish();
}
}
更新:(此解决方案对我有用)。
skipscreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE);
savestate.edit().putBoolean("skip", true).apply();
skip= true;
homeintent();
}
});
Thread splashthread = new Thread() {
@Override
public void run() {
try {
sleep(3000);
if (!skip) { homeintent();}
} catch (InterruptedException Interrupt) {
Interrupt.printStackTrace();
}
}
};
splashthread.start();
}
private void homeintent() {
if (!ThreadInterrupted) {
Intent i = new Intent(splash.this, home.class);
startActivity(i);
}
finish();
}
@Override
public void onBackPressed() {
SharedPreferences savestate= getSharedPreferences("ThreadInterrupted", MODE_PRIVATE);
savestate.edit().putBoolean("ThreadInterrupted", true).apply();
ThreadInterrupted = true;
homeintent();
}
}
当您在线程上调用 interrupt() 方法时,在睡眠状态下,将抛出 InterruptedException。
你可以在你的线程中检查天气它应该继续:
Thread splashthread = new Thread() {
@Override
public void run() {
while (shouldContinue) {
doSomeWork();
}
}
};
然后您可以在 onBackPressed 方法中将 shouldContinue 更改为 false:
@Override
public void onBackPressed() {
shouldContinue = false;
finish();
}
Udi 我已经回答了你的问题。 但我建议您使用 TimerTask and Timer 而不是 Thread.
Timer timer;
TimerTask timertask;
timer = new Timer();
timertask = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
homeintent();
}
});
}
};
timer.schedule(timertask, 3000);
@Override
public void onBackPressed() {
if(timertask!=null){
timertask.cancel();
}
if(timer!=null){
timer.cancel();
}
finish();
}
您可以创建一个 volatile boolean
检查以阻止线程继续进行,请参见以下代码:
private volatile boolean cancelled = false;
Thread splashthread = new Thread() {
@Override
public void run() {
if ( cancelled ) {
return; // or handle this however you want
}else{
// do what ever you want to do here
}
}
};
splashthread.start();
然后在 onBackPressed
中做这样的事情:
@Override
public void onBackPressed() {
cancelled = true;
finish();
}
建议使用 volatile 关键字,因为通常执行取消的线程不一定与被取消的线程相同。将 boolean
检查标记为 volatile
可确保检查标志的线程将看到最新值。
为了给您一个简洁的答案以及解释将来如何做,请看一下 Handler class and the Handler.postDelayed() 方法。
private Handler homeIntenthandler;
@Override
protected void onCreate(){
//other things
skipscreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE);
savestate.edit().putBoolean("skip", true).apply();
skip= true;
homeintent();
}
});
//initialise handler and set timer;
homeIntenthandler= new Handler();
homeIntenthandler.postDelayed(new Runnable() {
@Override
public void run() {
homeintent();
}
},3000);
}
}
private void homeintent() {
Intent i = new Intent(splash.this, home.class);
startActivity(i);
finish();
}
@Override
public void onBackPressed() {
if(homeIntenthandler!=null)
homeIntenthandler.removeCallbacksAndMessages(null)
finish();
}
}
Handler.removeCallbacksAndMessages(null)
基于为 same