我有一个线程需要耗费大量时间。这些任务是在c ++的native部分完成的。我想取消原生中正在进行的操作,代码就是这个地方。我可以重置一切。
mWorker = new WorkerThread("Worker thread");
mWorker.start();
//From Main thread:- Interrupting
mWorker.interrupt();
if(mWorker.isInterrupted()) {
Log.i(MOD_TAG, "Worker thread is interupptedd!!! ");
}
//Worker thread
public class WorkerThread extends Thread implements Runnable{
public void run() {
while(!Thread.currentThread().isInterrupted()) {
Looper.prepare();
mHandler = new WorkerHandler();
Looper.loop();
}
class WorkerHandler extends Handler {
@Override public void handleMessage(Message msg) {
try {
switch(msg.what) {
//do something native code
}
}
catch (Exception e) {}
}
}
}
}
即使workerthread被中断,我也无法在工作线程进行处理时向工作线程发送任何消息。我可以做一些事情来发布消息到workerthread或做一些其他可以让我在同一个线程中调用本机方法。
答案 0 :(得分:0)
在您的示例中,我不了解Handler在Thread中做了什么。一旦在运行中调用loop()
,该调用将阻塞,直到通过quit()或quitSafely()停止循环器。该调用基本上只是一个为消息收集队列的循环。你的中断检查永远不会发生。
我会推荐这样的东西。如果您希望代码由处理程序管理,您可以执行以下操作:
HandlerThread handlerThread = new HandlerThread("NativeHandler");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper()) {
public void handleMessage(Message msg) {
someObject.callNativeLongRunningFuction();
}
};
然而,中断仍然无法做任何事情,因为looper一次只处理一条消息。因此,如果它处理callNativeLongRunningFunction()
,那对你来说也无济于事。如果你想让中断停止jni通话的持续执行,我不认为这种方法可以完全适用于给定的信息。 java中的中断只设置一个标志,当调用wait()时,它会在检查并设置该标志时抛出异常。但是对于jni调用,没有调用wait(),java堆栈有点被阻塞,但它也不在wait()的中间。因此,除非您在本机运行时检查中断,否则该函数将继续运行。总的来说,我猜这可能不是你真正想要的。
如果是这样的话,我会推荐这样的东西。
public class NativeThreadTask {
public native void start();
public native boolean isRunning();
public native boolean cancel();
}
在该类的本机实现中,您将使用pThread来调用本机长时间运行的函数。 Start和Cancel将操纵那个在单独的线程中运行昂贵函数的pThread。使用pthread_cancel也可以中断该pthread实例。这会将长操作从线程移出运行时,同时仍允许您控制何时调用pthread中断机制但是在jni桥上。如果您甚至不想中断,并且如果长时间运行的本机调用正在迭代大量数据,则可能值得让cancel()简单地更改在本机函数的每次迭代中计算的bool #39; s循环。
因此,在给定的示例中,您可能会执行类似的操作。
NativeThread nativeThread = new NativeThread();
Handler handler = new Handler() {
public void handleMessage(Message message) {
NativeThread nativeThread = (NativeThread)message.obj;
switch(message.what) {
case 0:
if (!nativeThread.isRunning()) {
nativeThread.start();
}
break;
case 1:
if (nativeThread.isRunning()) {
nativeThread.cancel();
}
break;
default:
}
}
};