如何在没有崩溃的情况下中断线程onBackPressed?

时间:2021-10-25 03:00:34

I have tried overriding onBackPressed to not only finish the current activity but also to interrupt the thread as I am calling an intent to the next activity within. When I pressed back before, the splash activity finished, but the thread kept running and call the intent to the next activity. Now that I've include the thread interruption onBackPressed,the app crashes when I press back. What am I doing wrong?

我已经尝试重写onBackPressed,不仅要完成当前活动,还要中断线程,因为我调用了对下一个活动的意图。当我之前按下时,启动活动结束,但线程继续运行并将意图调用到下一个活动。现在我已经将线程中断包含在BackBack上,当我按下时,应用程序崩溃了。我究竟做错了什么?

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();
  }
}

UPDATED: (This solution has worked for me).

更新:(这个解决方案对我有用)。

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();
    }
}

4 个解决方案

#1


1  

To give you a succint answer as well as to explain how to do this in the future,take a look at the Handler class and the Handler.postDelayed() method.

为了给你一个succint答案以及解释将来如何做到这一点,请看一下Handler类和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();
      }
    }

the Handler.removeCallbacksAndMessages(null) is based on the documentation given for the same

Handler.removeCallbacksAndMessages(null)基于为其提供的文档

#2


1  

When you call interrupt() method on your thread, while in sleep, an InterruptedException will be thrown.

当您在线程上调用interrupt()方法时,在休眠状态下,将抛出InterruptedException。

You can check inside your thread weather it should continue:

您可以在线程天气内检查它应该继续:

 Thread splashthread = new Thread() {
    @Override
    public void run() {
           while (shouldContinue) {
                  doSomeWork();
           }
   }
};

You can then change shouldContinue to false in your onBackPressed method:

然后,您可以在onBackPressed方法中将shouldContinue更改为false:

@Override
public void onBackPressed() {
       shouldContinue = false;
       finish();
}

#3


0  

Udi I has answered your question. But i refer you to use TimerTask and Timer instead of Thread.

Udi我已经回答了你的问题。但我建议您使用TimerTask和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();
}

#4


0  

You can create a volatile boolean check to stop thread from progressing, see following code:

您可以创建一个volatile布尔检查来阻止线程进行,请参阅以下代码:

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();

And in onBackPressed do something like this:

在onBackPressed上做这样的事情:

@Override
public void onBackPressed() {
    cancelled = true;
    finish();
}

The volatile keyword is recommended because, generally, the thread doing the cancelling not necessarily will be the same thread that is being cancelled. Marking boolean check as volatile ensures that the thread checking the flag will see the up to date value.

建议使用volatile关键字,因为通常,执行取消的线程不一定与被取消的线程相同。将布尔检查标记为volatile可确保检查该标志的线程将看到最新值。

#1


1  

To give you a succint answer as well as to explain how to do this in the future,take a look at the Handler class and the Handler.postDelayed() method.

为了给你一个succint答案以及解释将来如何做到这一点,请看一下Handler类和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();
      }
    }

the Handler.removeCallbacksAndMessages(null) is based on the documentation given for the same

Handler.removeCallbacksAndMessages(null)基于为其提供的文档

#2


1  

When you call interrupt() method on your thread, while in sleep, an InterruptedException will be thrown.

当您在线程上调用interrupt()方法时,在休眠状态下,将抛出InterruptedException。

You can check inside your thread weather it should continue:

您可以在线程天气内检查它应该继续:

 Thread splashthread = new Thread() {
    @Override
    public void run() {
           while (shouldContinue) {
                  doSomeWork();
           }
   }
};

You can then change shouldContinue to false in your onBackPressed method:

然后,您可以在onBackPressed方法中将shouldContinue更改为false:

@Override
public void onBackPressed() {
       shouldContinue = false;
       finish();
}

#3


0  

Udi I has answered your question. But i refer you to use TimerTask and Timer instead of Thread.

Udi我已经回答了你的问题。但我建议您使用TimerTask和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();
}

#4


0  

You can create a volatile boolean check to stop thread from progressing, see following code:

您可以创建一个volatile布尔检查来阻止线程进行,请参阅以下代码:

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();

And in onBackPressed do something like this:

在onBackPressed上做这样的事情:

@Override
public void onBackPressed() {
    cancelled = true;
    finish();
}

The volatile keyword is recommended because, generally, the thread doing the cancelling not necessarily will be the same thread that is being cancelled. Marking boolean check as volatile ensures that the thread checking the flag will see the up to date value.

建议使用volatile关键字,因为通常,执行取消的线程不一定与被取消的线程相同。将布尔检查标记为volatile可确保检查该标志的线程将看到最新值。