当前位置: 首页 > 面试题库 >

在Android上调用返回JSON响应的HTTP Web API调用的最有效方法是什么?

松铭
2023-03-14
问题内容

我是完美主义者,我已经使Web API调用与Google Places
API配合得很好(仅作为示例),但是我感觉有时速度很慢,或者我做得不好。一些博客说我应该使用AndroidHttpClient,但不是,应该吗?

Web API调用我正在使用return
json,并且我不在UI线程上运行它们,因此使用AsyncTask(AsyncTask是在后台线程上运行的最有效方法,还是我应该使用其他方法?)

请查看我的代码,并告诉我如何才能更高效

public static class NearbySearchRequest extends AsyncTask<String, Void, JSONObject>
{
    Exception mException = null;

    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
        this.mException = null;
    }

    @Override
    protected JSONObject doInBackground(String... params)
    {
        StringBuilder urlString = new StringBuilder();
        urlString.append("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
        urlString.append("key=").append(Constants.GOOGLE_SIMPLE_API_KEY);
        urlString.append("&location=").append(params[0]);
        urlString.append("&sensor=").append("true");
        urlString.append("&language=").append("en-GB");
        urlString.append("&name=").append(params[1]);
        urlString.append("&rankby=").append("distance");

        LogHelper.Log(urlString.toString());

        HttpURLConnection urlConnection = null;
        URL url = null;
        JSONObject object = null;

        try
        {
            url = new URL(urlString.toString());
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.connect();
            InputStream inStream = null;
            inStream = urlConnection.getInputStream();
            BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));
            String temp, response = "";
            while ((temp = bReader.readLine()) != null)
                response += temp;
            bReader.close();
            inStream.close();
            urlConnection.disconnect();
            object = (JSONObject) new JSONTokener(response).nextValue();
        }
        catch (Exception e)
        {
            this.mException = e;
        }

        return (object);
    }

    @Override
    protected void onPostExecute(JSONObject result)
    {
        super.onPostExecute(result);

        if (this.mException != null)
            ErrorHelper.report(this.mException, "Error # NearbySearchRequest");
    }
}

问题答案:

您正在使用的Http引擎似乎是最佳选择。实际上,任何其他第三方引擎都基于Apache或HttpUrlConnection。我更喜欢将Spring用于Android,因为该API提供了Http
Engine之上的抽象,并且您实际上不需要关心如何根据API级别使用什么API。或者,您可以使用Volley-一个非常时尚的图书馆。

但是,我会触摸您的一些代码:

  1. 如果读取流时出现异常怎么办?然后,流保持打开状态,并保持连接状态。因此,无论您是否遇到异常,我都建议在finally块中关闭流和连接:
        HttpURLConnection urlConnection = null;
    URL url = null;
    JSONObject object = null;
    InputStream inStream = null;
    try {
        url = new URL(urlString.toString());
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");
        urlConnection.setDoOutput(true);
        urlConnection.setDoInput(true);
        urlConnection.connect();
        inStream = urlConnection.getInputStream();
        BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));
        String temp, response = "";
        while ((temp = bReader.readLine()) != null) {
            response += temp;
        }
        object = (JSONObject) new JSONTokener(response).nextValue();
    } catch (Exception e) {
        this.mException = e;
    } finally {
        if (inStream != null) {
            try {
                // this will close the bReader as well
                inStream.close();
            } catch (IOException ignored) {
            }
        }
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
  1. JSON解析:您正在使用Android标准的JSON解析方式,但这并不是最快,最简单的方法。GSON和Jackson更好用。为了进行 JSON解析器的比较,我将选择Jackson。这是关于此比较的另一个SO主题。

  2. 不要像这样串联字符串,因为串联字符串会在每次创建另一个字符串时创建。请StringBuilder改用。

  3. 异常处理(在所有编程论坛中,这都是一个长期辩论的主题)。首先,您必须将其记录下来(Log不使用class System.out.printXXX)。然后,您需要通知用户:您敬酒一条消息,显示标签或通知。该决定取决于用户情况以及您进行的呼叫的相关程度。

这些是我在您的代码中看到的主题。

编辑 我意识到我没有回答这个问题:is AsyncTask the most efficient way to run on background thread or should I use something else?

我要给出的简短答案是:如果您应该执行短时的请求,那AsyncTask是完美的。但是,如果您需要获取一些数据并进行显示-
但又不想担心屏幕旋转等情况下是否再次下载,我强烈建议您通常使用an
AsyncTaskLoaderLoaders

如果您需要下载一些大数据,则可以使用IntentService或进行繁重的操作DownloadManager

享受编码!



 类似资料:
  • 本文向大家介绍调用下面的方法,得到的返回值是什么?相关面试题,主要包含被问及调用下面的方法,得到的返回值是什么?时的应答技巧和注意事项,需要的朋友参考一下 代码走到第3行的时候遇到了一个MathException,这时第4行的代码就不会执行了,代码直接跳转到catch语句中,走到第 6 行的时候,异常机制有一个原则:如果在catch中遇到了return或者异常等能使该函数终止的话那么有finall

  • 问题内容: 我们的应用程序必须以最少的远程http请求显示大量数据,因此我们在后端添加了一个终结点,该终结点将所有必要的数据作为单个json响应提供。这导致〜1.5MB(压缩)或大约8MB的未压缩json格式的文本。 没什么大问题,它会在10到30秒内下载完毕,我们正在使用ASIHTTPRequest将整个响应写入磁盘。 现在来了有趣的部分-将未压缩的文件读入内存映射的字符串后,我们使用stig的

  • 不知何故,循环没有正确执行(我相信),当我使用循环时,对服务器的调用永远不会完成(没有循环时会完成) 请参见以下代码 客户端:主控制器 我认为这就是问题所在:循环阻止了异步REST调用的进行,从而使其无法终止。 我的问题是:A)如何将从服务器收到的Login-Object返回到首先调用MainController.getLoginbyUsername-function的函数? B)我试图用于等待的

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

  • 按照说明:编写一个静态方法,将一个整数作为形参,如果参数值为偶数,则返回布尔值True,如果参数值为奇数,则返回False。我的方法似乎必须调用int而不是布尔值。话虽如此,我不知道如何从调用int的方法返回布尔值。我试过了,但不管用。 编辑语言是Java。\nedit 2-对于将来关注此问题的人来说,我最初的意思是键入私有静态int result。不是私有的静态布尔结果。那个错误最终修复了我的代

  • 本文向大家介绍什么是方法的返回值?返回值在类的方法里的作用是什么?相关面试题,主要包含被问及什么是方法的返回值?返回值在类的方法里的作用是什么?时的应答技巧和注意事项,需要的朋友参考一下 方法的返回值是指我们获取到的某个方法体中的代码执行后产生的结果!(前提是该方法可能产生结果)。 返回值的作用: 接收出结果,使得它可以用于其他的操作!