【问题标题】:Android/Java : Is there a way to call the return of the method after a listener triggered?Android/Java:有没有办法在监听器触发后调用方法的返回?
【发布时间】:2019-11-20 18:51:56
【问题描述】:

我正在使用 Volley 从 HTTP Api 获取 JSONObject。

我的问题是我希望我的方法等待 Response Listener 得到结果,否则我的方法返回一个空对象。
我尝试使用同步等待和通知来实现它,但它似乎不起作用,活动在 isFinished.wait() 之后冻结并且侦听器没有触发。你能告诉我我的代码有什么问题吗?

public JSONObject query(String url) throws InterruptedException {
    finished=false;
    Req = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            synchronized (isFinished){
                Retour = response;
                finished = true;
                isFinished.notifyAll();
            }
        }
    },
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            synchronized (isFinished){
                Retour = null;
                finished = true;
                isFinished.notifyAll();
            }
        }
    });
    Queue.add(Req);
    synchronized (isFinished) {
        while (!finished) {
            isFinished.wait();
        }
        return Retour;
    }
}

【问题讨论】:

  • 'wait for the Response Listener' 意味着阻塞主线程,你的 ui 会卡住一段时间,系统会显示你的应用没有响应..
  • 我建议通过自定义侦听器对象来更改设计,该对象将在触发 onResponse() 或 onErrorResponse() 时触发。你想要的是一个挂起的函数,它在 Kotlin 中可用,但在 Java 中不容易实现。所以我推荐一种不同的设计方法。
  • 您还可以查看CountdownLatch 并了解它如何用于发送信号。
  • @Jarvis 感谢您的建议,我通过将回调函数(使用 Consumer)作为参数传递给方法解决了我的问题。然后由 Response 侦听器调用它,而不会中断我的主线程。

标签: java android multithreading monitor notify


【解决方案1】:

我通过更改设计解决了这个问题,因此该方法不返回任何内容,而是回调一个 Consumer 接口,然后将 Result 检索到类字段 Data

Consumer<JSONObject> cons = a -> Data=a;

原来的代码变成了:

public void query(String url,Consumer<JSONObject> cons) {
    Req = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            Retour = response;
            callb.accept(Retour);
        }
    },
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Retour = null;
            callb.accept(null);
        }
    });
    Queue.add(Req);
}

【讨论】:

    猜你喜欢
    • 2014-12-10
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 2012-03-02
    • 1970-01-01
    相关资源
    最近更新 更多