我正在后台运行一项服务,该服务也绑定到一个活动,以向视图提供一些数据结果。 所以我的服务在后台运行,我在活动开始时绑定服务,并在关闭时解除绑定,而不管我的后台服务是否在不断运行。 当我的活动第一次开始时,该服务首先被触发。
现在我在服务中创建了两个线程。一个用于后台工作。其他线程" displayThread"用于获取数据并将数据推送到活动。
现在我的显示线程是这样的:
Thread displayThread = new Thread(new Runnable() {
@Override
public void run() {
try {
executeDisplayQueue();
} catch (InterruptedException e){
displayThread.interrupt();
}
}
});
所以当我的活动开始时我的服务开始了,我开始了两个线程:
@Override
public void onCreate() {
super.onCreate();
Log.d(LOG_TAG, "Creating Service......");
thread.start();
displayThread.start();
Log.d(LOG_TAG, "Service is created.");
}
现在我想要的是当我在活动关闭我的" displayThread"停止或暂停,重新启动或重新启动,再次启动活动,调用rebind()函数。
@Override
public boolean onUnbind(Intent intent) {
super.onUnbind(intent);
// Stop/Pause/Wait my displayThread here
return true;
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
// Restart/Resume my displayThread here
Log.d(LOG_TAG, "trying to check display thread");
}
请在这里帮助我,因为我尝试了很多东西。 现在displayThread.wait()暂停我的应用程序屏幕,所以它变黑了,好像一切都停止了,这当然不是正确的方法。
请给我一个如何进一步处理的解决方案。
这是executeDisplayQueue()函数:
@Override
protected void executeDisplayQueue() throws InterruptedException {
Log.d(LOG_TAG, "Starting execution of queue...");
while (!Thread.currentThread().isInterrupted()) {
SomeJob job = null;
try {
job = jobShowQueue.take();
Log.d(LOG_TAG, "Taking Job no. " + job.getId() + " from the queue...");
if (job.getJobState().equals(JobState.NEW)) {
Log.d(LOG_TAG, "Job state is NEW.");
job.setJobState(JobState.RUNNING);
job.getCmd().run(bluetoothSocket.getInputStream(), bluetoothSocket.getOutputStream());
} else {
Log.e(LOG_TAG, "Job state is not NEW and therefore it should not be in Queue");
}
} catch (InterruptedException ie){
Thread.currentThread().interrupt();
} catch (UnsupportedCommandException u) {
if (job != null)
job.setJobState(JobState.NOT_SUPPORTED);
} catch (IOException ioe){
job.setJobState(JobState.BROKEN_PIPE);
Log.e(LOG_TAG, "Broken Pipe Error. Close the connection and restart again: "+ioe.getMessage());
} catch (Exception e){
job.setJobState(JobState.EXECUTION_ERROR);
Log.e(LOG_TAG, "Failed to run Command. Error: "+e.getMessage());
}
if (job != null){
Log.d(LOG_TAG, "Job is Finished.");
final SomeJob finalJob = job;
((Activity) applicationContext).runOnUiThread(new Runnable() {
@Override
public void run() {
((Activity) applicationContext).stateUpdate(finalJob);
}
});
}
}
}
所以基本上我一个接一个地从队列中取出工作并在活动中填充它。因此,当我的活动关闭时,我希望此线程(displayThread)停止,因为它不再需要填充任何内容。当它再次打开时,我的displayThread应该重新开始。
答案 0 :(得分:1)
您可以使用线程锁。方法“executeDisplayQueue”中是否有while循环?您应该将if(){lock.wait()}放在while循环中。
private final Object displayThreadLock = new Object();
private boolean mIsBound;
Thread displayThread = new Thread(new Runnable() {
@Override
public void run() {
synchronized(displayThreadLock) {
if (!mIsBound) {
displayThreadLock.wait(); // this thread will wait here util displayThreadLock.notify() is called
}
try {
executeDisplayQueue();
} catch (InterruptedException e){
displayThread.interrupt();
}
}
}
});
@Override
public boolean onUnbind(Intent intent) {
super.onUnbind(intent);
// Stop/Pause/Wait my displayThread here
mIsBound = false;
return true;
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
// Restart/Resume my displayThread here
mIsBound = true;
synchronized(displayThreadLock) {
displayThreadLock.notify(); // call notify to break the wait, so the displayThread continues to run
}
Log.d(LOG_TAG, "trying to check display thread");
}
答案 1 :(得分:0)
由于你的displayThread中有一个针对InterruptedException的try-catch块,你可以通过以下方式停止该线程:
displayThread.interrupt();
并在重新绑定时再次启动displayThread:
displayThread.start();
顺便问一下,你能展示executeDisplayQueue()的方法体吗?我需要知道你的情况下这是否安全。
您需要处理一个额外的问题。在displayThread被中断后,这意味着您的活动不再存在,您无法安排作业。