在下面,您会看到一些运行良好的代码-但只有一次。它被阻止直到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;
}


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

最佳答案

您可以尝试在Callable而不是FutureTask内使用Runnable效果更好。据我了解,该组合旨在提供线程的返回值。

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


Callable类似于Runnable,但具有返回值。

FutureTask进行同步并等待结果。与您的wait() / notify()相似。 FutureTask还实现了Runnable,因此可用于runOnUiThread

07-27 19:28