Java Android Native线程问题

时间:2014-09-18 15:27:06

标签: android multithreading handler

我有一个线程需要耗费大量时间。这些任务是在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或做一些其他可以让我在同一个线程中调用本机方法。

1 个答案:

答案 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:
          }
   }

};