当前位置: 首页 > 知识库问答 >
问题:

如何向调用函数返回响应?(通过JSON调用Java REST服务器的Android应用程序)

王俊楚
2023-03-14

不知何故,循环没有正确执行(我相信),当我使用循环时,对服务器的调用永远不会完成(没有循环时会完成)

请参见以下代码

客户端:主控制器

class MainController
{
    private final AtomicLong counter;
    private final HashMap<Long, Object> callResults;

    public MainController(){
        counter = new AtomicLong();
        callResults  = new HashMap<>();
    }

    public Login getLoginByUsername(String username)
    {
        long callID = counter.incrementAndGet();
        System.out.println("Start call");
        ServerConnection.get("myURL",null, new JsonHttpResponseHandler(){
            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response){
                try {
                    System.out.println("Call success, enter result:");
                    callResults.put(callID, new CallResult(Login.parseFromJson(response)));
                    System.out.println(callResults.get(callID));

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });

        System.out.println("start waiting");
       while(callResults.get(callID) == null){
            System.out.print(".");
        }
        System.out.println("waiting over, return result:");
        System.out.println(callResults.get(callID));
        //return (Login) callResults.remove(callID).content;
        return null;
    }
}
import com.loopj.android.http.*;
import cz.msebera.android.httpclient.HttpEntity;

public class ServerConnection {

    private static final String BASE_URL = "http://1.3.3.7:8080/";

    private static AsyncHttpClient client = new AsyncHttpClient();

    public static void get(String url, RequestParams params, JsonHttpResponseHandler responseHandler) {
        client.get(BASE_URL+url, params, responseHandler);
    }
}

我认为这就是问题所在:循环阻止了异步REST调用的进行,从而使其无法终止。

我的问题是:A)如何将从服务器收到的Login-Object返回到首先调用MainController.getLoginbyUsername-function的函数?

B)我试图用于等待的while-loop是怎么回事?为什么主体(print(".“);)不会被执行,更重要的是,为什么它会停止REST调用表单的执行/完成?

编辑:增加了问题B,可能会提供一个更容易找到快速解决方案的方法

编辑到更新:很抱歉没有把这一点说得足够清楚:任何需要我修改调用函数的建议(例如,像LiveDataRxjava这样的观察者模式,或者Leo Pelozo提供的其他非常好的建议)都是不可行的。我至少测试了Leo Pelozos的建议,底层代码根本不允许这样做。我失去了对参数的访问,不能再利用函数返回了。我知道,重新设计底层系统是最好的做法,但现在这根本超出了范围...

共有1个答案

常英毅
2023-03-14

谢谢你的帮助!我找到了一个适合我案子的解决方案。

首先,由于这只是一个原型,我并不真的需要我的请求是异步的,所以我将ServerConnection改为使用SynchTtpClient:

public class ServerConnection {

    private static final String BASE_URL = "http://10.203.58.11:8080/";

    private static SyncHttpClient client = new SyncHttpClient();

    public static void get(String url, RequestParams params, JsonHttpResponseHandler responseHandler) {
        client.get(getAbsoluteUrl(url), params, responseHandler);
    }
}

然后,Android不允许我在主线程上执行请求。对于AsynchTtpClient来说,这不是一个问题,因为异步部分是在自己的线程中处理的。所以我不得不在我的请求中添加线程。因此,我的maincontroller现在看起来如下所示:

public class MainController
{
    private final AtomicLong counter;
    private final HashMap<Long, CallResult> callResults;

    public MainController(){
        counter = new AtomicLong();
        callResults  = new HashMap<>();
    }

public Login getLoginByUsername(String username)
    {
        long callID = counter.incrementAndGet();
        new Thread(new Runnable() {
            @Override
            public void run() {
                ServerConnection.get("person-login-relations?byUsername="+username,null, new JsonHttpResponseHandler(){
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, JSONObject response){
                        try {
                            callResults.put(callID, new CallResult(Login.parseFromJson(response)));
                            System.out.println(callResults.get(callID));

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });


            }
        })   .start();

        while(callResults.get(callID) == null){
            //wait
        }
        return (Login) callResults.remove(callID).content;
    }
}

我想我用来等待的while-loop现在起作用了,因为它没有阻塞负责执行和处理请求的线程。不过,我不完全确定。

诚然,这可能不是理想的解决方案,但考虑到我的具体情况,这是最可行的。

几个月后,我将被要求重新工作我现在扩展的应用程序,以连接到客户机。在这一点上,我将确保实施您的大部分建议!因此,对于任何阅读此解决方案的人来说:这里是一个变通方法,因为我不需要异步请求,也不应该更改调用您在这里看到的方法的函数!我建议你还是阅读其他的回复,因为它们在质量上更好!

 类似资料:
  • 问题内容: 我有一个发送Ajax命令的系统,该命令返回一个带有功能的脚本块。将此数据正确插入DIV后,我希望能够调用此函数来执行所需的操作。 这可能吗? 问题答案: 我想以这种形式正确解释您的问题:“好的,我已经用完所有的Ajax东西了;我只想知道从那时起任何时候都可以调用插入到DIV中的JavaScript函数吗? ,也就是说,我不想在上下文中将其称为“回调返回”。 好的,如果您的意思是这样,那

  • 问题内容: 我有一个发出异步请求的函数。我如何从中返回响应/结果? 我尝试从回调中返回值,以及将结果分配给函数内部的局部变量并返回该局部变量,但这些方法均未真正返回响应(它们都返回或变量的初始值为任意值) 。 使用jQuery函数的示例: 使用node.js的示例: 使用承诺块的示例: 问题答案: 在 一 中的Ajax代表 异步 。这意味着发送请求(或接收响应)已从正常执行流程中删除。在您的示例中

  • 使用promise的块的示例:

  • 问题内容: 我如何使这个小功能“ imageExists”返回ajax请求是否成功? 问题答案: 我相信您将必须使用同步模式并使用单独的变量来存储返回值。

  • 问题内容: 我有一个发出Ajax请求的函数。我如何从中返回响应? 我尝试从回调中返回值,以及将响应分配给函数内部的局部变量并返回该局部变量,但这些方法均未真正返回响应。 问题答案: 问题 在一中的Ajax代表异步。这意味着发送请求(或更确切地说接收响应)已从正常执行流程中删除。在你的示例中,立即返回并且在调用;作为回调传递的函数之前执行下一条语句。 这是一个类比,希望可以使同步流和异步流之间的区别

  • 问题内容: 谁能告诉我如何将值作为函数的返回值返回。 当您点击注册表格中的提交时,上述功能就会触发(很明显)。问题是,无论响应是什么,此表单都将提交,并且警告框有时不显示任何内容(空白),有时根本不显示。但是,如果我将结尾更改为手动[即用] 替换,则正确的值将显示在警报框中。 PS我比JavaScript的菜鸟还差,因此也欢迎提出一般性改进代码的建议。 问题答案: 问题是,直到……等待……状态改变