2

下面你会看到一些运行良好的代码 - 但只有一次。它应该阻塞,直到 runOnUIThread 完成。它确实如此,当它第一次运行时被调用。但是当第二次调用时,它一直运行到最后,然后runOnUIThread开始运行。可能是,第一次运行方法后,调用它的线程仍然有锁,当它第二次调用方法时,它运行了。这是正确的吗?我能做些什么来解决这个问题?还是时间问题,第二次调用者先拿到锁?

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;
}

背景:调用此方法的线程是绑定服务中的异步任务,该服务在后台与银行进行交易。银行不定期发送用户验证请求(验证码、控制问题、密码请求等),并且服务必须显示一些对话,以针对前台活动的弱引用回调。由于该服务正在执行多个嵌套的 while 循环,因此同步显示对话框比停止重新启动服务更容易(保存/恢复状态数据太复杂)。

4

1 回答 1

2

如果使用Callable内部 aFutureTask而不是 aRunnable效果更好,您可以尝试。据我了解,这种组合旨在提供线程的返回值。

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;
}

ACallable类似于 aRunnable但有返回值。

AFutureTask进行同步并等待结果。类似于您的wait()/ notify()FutureTask也实现Runnable了,所以它可以用于runOnUiThread.

于 2012-11-01T18:33:16.157 回答