我的活动有两个名为图片和视频的复选框。在我的服务中,我正在针对这两个复选框名称 imagethread 和 videothread 运行两个主题。如果用户检查图像复选框,我将启动服务并启动图像线程。并且如果用户取消选中它我停止服务。如果用户取消选中该框,停止服务并停止线程,我想做。现在我有两个问题
我无法停止服务中的线程
例如,如果用户取消选中视频复选框,我如何在我的 onDestroy()方法中识别出音频复选框已被选中,所以现在停止音频线程而不是图像,因为它已被选中。
这是我的代码剪断了我的第一个问题
public synchronized void onDestroy()
{
image_thread_running = false;
super.onDestroy();
if(image_thread_running){
system.out.println("stop thread"); //message is successfully printing on a console
imageThread.interrupt(); //its not working.
}
}
public synchronized void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
image_thread_running = true;
this.intent = intent;
String myString = intent.getStringExtra("name");
if(myString.equalsIgnoreCase("image"))
{
if(image_thread_running){
imageThread.start();
}
}else if(myString.equalsIgnoreCase("audio")){
audioThread.start();
}
}
class ImageThread extends Thread
{
@Override
public void run()
{
if (image_thread_running){
System.out.println("Service running");
try {
if(checkInternetConnection()){
UploadFiles();
Thread.sleep(interval);
}else{
Log.d("msg","internet is not connected");
}
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
所以例如,如果我成功获得上面的代码工作意味着线程正在成功停止,所以它导致我的第二个问题,现在我如何识别来自视频复选框的消息以停止视频线程。因为通过更改onDestroy()
中的bool值会导致更改bool值image_thread_running和video_thread_running。希望你能理解我的问题
答案 0 :(得分:0)
有一段时间.stop()
已被弃用,因为它可能会以不安全的方式终止您的Thread
。
最常见的方法是在boolean
内部设置Thread
控制器,检查是否发生了某些操作(在您的情况下,已选中/取消选中复选框),如果是,则在下一个循环迭代,只需在return
中使用Thread
即可。这将彻底和安全地终止它。您甚至可以使用它来停止服务,因此如果您退出Thread
,则意味着您也必须退出Service
。
假设这是您CheckBox
的{{1}}:
onClickListener()
答案 1 :(得分:0)
你需要让线程句柄中断 - 换句话说,线程必须认识到你调用了中断并做了退出线程所需的一切。
void run() {
while(!Thread.isInterrupted()) {
// do work
}
}
只有在线程中执行InterruptedException
或Thread.sleep()
等可中断方法时才会出现Thread.wait()
。否则,它只会设置一个标记,您可以使用Thread.interrupted()
或Thread.isInterrupted()
来检查。
因此,您需要检查线程中的状态以查看它是否已被中断,以使interrupt()
调用生效。
在Java theory and practice: Dealing with InterruptedException处非常清楚地解释了这一点。
每个线程都有一个与之关联的布尔属性 它的中断状态。中断状态最初为假; 当一个线程被某个其他线程通过调用中断时 Thread.interrupt(),两件事之一发生。如果该线程是 执行低级可中断阻塞方法,如 Thread.sleep(),Thread.join()或Object.wait(),它取消阻塞和 抛出InterruptedException。否则,interrupt()只会设置 线程的中断状态。代码在中断的线程中运行 以后可以轮询中断状态以查看是否已请求 停止它正在做的事;可以读取中断状态 Thread.isInterrupted()可以在单个中读取和清除 使用命名不佳的Thread.interrupted()进行操作。
该页面还解释了如何处理InterruptedException
。
对于您在图片主题中所做的工作(上传文件),我建议您使用IntentService
。使用IntentService还会将任务与活动的生命周期分离,例如,它可以继续进行方向更改,或在用户导航到其他活动后完成其工作。与Service
不同,IntentService
在单独的线程中运行,处理工作线程将由您负责。 (您也可以轻松地实现任务队列,或者从一个任务链接到另一个任务,只需处理onHandleIntent
中的不同操作。)