我有2个Activty:A和B. 第一个(A)创建并启动3个线程。
当用户插入第二个活动(B)时,我需要暂停所有线程,直到用户返回A活动。
我尝试使用onPause()和onResume(),但它似乎不好,也不起作用:(在活动a上)
@Override
public void onPause()
{
Const.isWainting = true;
super.onPause();
try {
synchronized(Const.shop){
Const.shop.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onResume()
{
super.onResume();
if(Const.isWainting == true){
synchronized(Const.shop){
Const.shop.notifyAll();
Const.isWainting = false;
}
}
}
编辑:以下建议解决方案之后的运行方法之一:
@Override
public void run()
{
while (true)
{
if (this.isInterrupted() && Const.isWainting){
synchronized (Const.shop) {
try {
Const.shop.wait();
Const.isWainting = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
for(int i=0; i<Const.MAX_FOOD ; i++){
if(foodArr[i].getStatus() != Const.NOT_ACTIVE){
//move the food one step
foodArr[i].move();
if(foodArr[i].getY() > Const.screenHeight){
foodArr[i].setStatus(Const.NOT_ACTIVE);
}
gameView.postInvalidate();
}
}
if (isInterrupted() && Const.isWainting){
synchronized (Const.shop) {
try {
Const.shop.wait();
Const.isWainting = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
try
{
FoodThread.sleep(5);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我知道线程不会停止,因为食物继续下降,即使在一个循环中“移动”只有一个像素 - &gt;所有的食物从屏幕上消失,或者向下移动......
请帮助,非常感谢!
编辑2: 活动:
@Override
public void onPause()
{
super.onPause();
Const.isWainting = true;
this.threadAnimal.interrupt();
this.threadFood.interrupt();
this.threadMoney.interrupt();
}
@Override
public void onResume()
{
super.onResume();
Const.isWainting = false;
if(Const.isWainting == true){
synchronized(Const.shop){
Const.shop.notifyAll();
}
}
}
其中一个主题:
@Override
public void run()
{
while (true)
{
if (this.isInterrupted() && Const.isWainting){
synchronized (Const.shop) {
try {
Const.shop.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
for(int i=0; i<Const.MAX_FOOD ; i++){
if(foodArr[i].getStatus() != Const.NOT_ACTIVE){
foodArr[i].move();
if(foodArr[i].getY() > Const.screenHeight){
foodArr[i].setStatus(Const.NOT_ACTIVE);
}
gameView.postInvalidate();
}
}
if (isInterrupted() && Const.isWainting){
synchronized (Const.shop) {
try {
Const.shop.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
try
{
FoodThread.sleep(5);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
答案 0 :(得分:2)
这是一个非常糟糕的设计。如果你在一个Activity中启动一个线程并将它停在onStop()上,那么活动就会被破坏(并且你的线程也会被破坏),但最糟糕的情况是:激活不能在后台被破坏 - 繁荣的大量内存泄漏 - 你得到一个新的活动,但旧的活动可以被解除引用。
使用services更好地处理这种用例
答案 1 :(得分:0)
当您在shop.wait()
中调用时,您正在从主线程中调用onPause
。您必须从要停止的线程中调用它。首先,不要将Const.isWaiting
用作公共变量,而是将其设为私有,并为其提供同步的getter和setter(例如isWaiting()
和setWaiting(boolean waiting)
)。 (但这一步可能是不合理的,因为我认为单个布尔值已经是线程安全的。)
然后:
@Override
public void onPause()
{
super.onPause();
Const.setWaiting(true);
for (Thread t in myThreeThreads) {
try {
t.interrupt();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
在每个线程中,无论他们执行什么循环,他们都应该定期执行:
if (isInterrupted() && Const.isWaiting()){
synchronized (Const.shop) {
Const.shop.wait();
}
}
或者如果他们也在进行非循环操作,请在每次长时间运行之前执行上述操作。
编辑:我认为您还应该更新onResume
以确保首先取消设置isWaiting
变量。
@Override
public void onResume()
{
super.onResume();
Const.setWaiting(false); //Now if a thread is just now getting to an interrupt check, it can just skip it and keep going.
synchronized(Const.shop){
Const.shop.notifyAll();
}
}