2

onIncomingCall() is a overridden method from a class in third party library pjsip. This method is called when an incoming call is made using SIP. Somehow this method makes it possible for the call to be answered ONLY if the Call answering code be inside the same method or called within the same method. But I want the call to be answered when the user presses the button. I have created a call back and make the user press the button when the call comes but the call answering code is not working if its called outside of onIncomingCall() method. So I decided to put Thread.sleep(10000) in onIncomingCall() and when the user presses the button I would like to cancel this thread so that the call answering code can be executed.

I used Thread.currentThread().interrupt() but the Thread.sleep is not cancelled at all. I wrote a separate activity to test this functionality but it failed, meaning Thread.currentThread.interrupt is not working in for me at all. What is the best option to achieve this? Kindly please update me .. I am really struggling with this.

@Override
public void onIncomingCall(OnIncomingCallParam prm) {

    onIncomingCallParam = prm;

    try  {
        Thread.sleep(10000);
    } catch(InterruptedException ie) {
        ie.printStackTrace();
    }

    answerCall();
}

UPDATE:

I fixed the issue with the below approach

resetThread();
while (testThread) {
    try {
        Log.d(TAG,"testThread true");
        Thread.sleep(1000);
    } catch (InterruptedException ie) {
        ie.printStackTrace();
    }

}

Log.d(TAG,"Call Answering code");


private void resetThread() {
        Thread newThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                    testThread = false;
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }
            }
        });
        try {
            newThread.start();
        } catch (Exception ie) {
            ie.printStackTrace();
        }
    }
praneel
  • 241
  • 2
  • 14
  • 2
    You must be calling `interrupt()` from a thread (A) that is different from the thread that is sleeping (B). So from thread A, you need to call `threadB.interrupt()` - at the moment you are interrupting thread A, which makes no sense. – assylias Oct 04 '16 at 11:22
  • @assylias Thread.sleep is called on a Thread. How would you differentiate between thread A and Thread B – praneel Oct 04 '16 at 11:36
  • You could use a variable (probably needs to be volatile) in `onIncominCall()`: `sleepingThread = Thread.currentThread();` and in your other code, call `sleepingThread.interrupt()`. But more likely you should change your design - using `Thread.sleep()` is definitively a code smell. – assylias Oct 04 '16 at 11:48

2 Answers2

3

The problem here is related to the fact that you don't interrupt the right Thread, if you call Thread.currentThread().interrupt(), you will interrupt the current thread not the one that it is currently sleeping.

Here is a clear example to show the main idea:

// Here is the thread that will only sleep until it will be interrupted
Thread t1 = new Thread(
    () -> {
        try {
            Thread.sleep(10_000L);
            System.err.println("The Thread has not been interrupted");
        } catch (InterruptedException e) {
            System.out.println("The Thread has been interrupted");
        }
    }
);
// Start the thread
t1.start();

// Make the current thread sleep for 1 sec
Thread.sleep(1_000L);
// Try to interrupt the sleeping thread with Thread.currentThread().interrupt()
System.out.println("Trying to call Thread.currentThread().interrupt()");
Thread.currentThread().interrupt();
// Reset the flag to be able to make the current thread sleep again
Thread.interrupted();

// Make the current thread sleep for 1 sec
Thread.sleep(1_000L);
// Try to interrupt the sleeping thread with t1.interrupt()
System.out.println("Trying to call t1.interrupt()");
t1.interrupt();

Output:

Trying to call Thread.currentThread().interrupt()
Trying to call t1.interrupt()
The Thread has been interrupted

As you can see in the output, the thread is interrupted only when we call t1.interrupt(), in other words only when we interrupt the right Thread.

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • I am actually NOT doing anything Thread specific here.. I literally need a way to break the code in between that method till the user responds for the incoming call and once responded, I need to continue in the same method – praneel Oct 04 '16 at 12:16
0

Maybe all calls has to be done on the same thread, which created library instance. Try using HandlerThread for posting it messages and handle those messages inside custom Handler instead of suspending thread.

Alex Shutov
  • 3,217
  • 2
  • 13
  • 11