2

Below you see some code that works fine - but only once. It is suppsed to block until the runOnUIThread is finished. And it does, when it runs the first time it is called. But when called the second time, it runs through to the end, then the runOnUIThread starts running. It could be, that after the methos was run the first time, the thread that caled it still has the lock, and when it calls the method the second time, it runs through. Is this right? And what can I do to fix that? Or is it a timing problem, the second time the caller gets the lock first?

static Integer syn = 0;
@Override 
public String getTanFromUser(long accid, String prompt) {
    // make parameters final
    final long accid_int = accid;
    final String prompt_int = prompt;
    Runnable tanDialog = new Runnable() {
        public void run() {
            synchronized(syn) {
                tanInputData = getTANWithExecutionStop(TransferFormActivity.this);
                syn.notify() ;
            }
        }
    };
    synchronized(syn) {
        runOnUiThread(tanDialog);
        try {syn.wait();} 
        catch (InterruptedException e) {} 
    }
    return tanInputData;
}

Background: The thread that calls this method is an asynctask inside a bound service that is doing transactions with a bank in the background. At unregular intervalls the bank send requests for user verification (captche, controll questions, requests for pin, etc.) and the service must display some dialogs vis a weak-referenced callback to the activities in the foreground. Since the service is doing several nested while-loops, it is easier to show the dialogs synchroniously than stopping an restarting the service (savind/restoring the state data would be too complex).

1 Answer 1

2

You could try if using a Callable inside a FutureTask instead of a Runnable works better. That combination is as far as I understand meant to provide return values from threads.

public String getTanFromUser(long accid, String prompt) {
    // make parameters final
    final long accid_int = accid;
    final String prompt_int = prompt;
    Callable<String> tanDialog = new Callable<String>() {
        public String call() throws Exception {
            return getTANWithExecutionStop(TransferFormActivity.this);
        }
    };
    FutureTask<String> task = new FutureTask<String>(tanDialog);
    runOnUiThread(task);
    String result = null;
    try {
        result = task.get();
    }
    catch (InterruptedException e) { /* whatever */ }
    catch (ExecutionException e) { /* whatever */ }
    return result;
}

A Callable is like a Runnable but has a return value.

A FutureTask does the synchronization and waits for the result. Similar to your wait() / notify(). FutureTask also implements Runnable so it can be used for runOnUiThread.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.