什么是Android上最有效的方式来调用返回一个JSON响应HTTP的Web API调用? [英] What is the most efficient way on Android to call HTTP Web API calls that return a JSON response?

查看:171
本文介绍了什么是Android上最有效的方式来调用返回一个JSON响应HTTP的Web API调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是完美主义者的类型,我已经有了网络的API调用工作正常,与谷歌API的地方(就像一个例子),但我觉得这是有时慢或者我不这样做是正确的。一些博客说的话,我应该使用AndroidHttpClient,但我不是,我应该?

我使用的返回JSON,我不UI线程上运行它们,所以使用的AsyncTask该网站的API调用(是的AsyncTask对后台线程运行的最有效的方式还是应该用别的东西吗?)

请看看我的code,告诉我如何才能更有效地反正

 公共静态类NearbySearchRequest扩展的AsyncTask<字符串,无效的JSONObject>
{
    异常mException = NULL;

    @覆盖
    在preExecute保护无效()
    {
        super.on preExecute();
        this.mException = NULL;
    }

    @覆盖
    受保护的JSONObject doInBackground(字符串... PARAMS)
    {
        StringBuilder的urlString =新的StringBuilder();
        urlString.append(https://maps.googleapis.com/maps/api/place/nearbysearch/json?);
        urlString.append(键=)追加(Constants.GOOGLE_SIMPLE_API_KEY)。
        urlString.append(与&位置=)追加(PARAMS [0])。
        urlString.append(&放大器,传感器=)。追加(真);
        urlString.append(&放大器;语言=)追加(EN-GB)。
        urlString.append(&放大器;名称=)。追加(PARAMS [1]);
        urlString.append(与& rankby =)附加(距离)。

        LogHelper.Log(urlString.toString());

        HttpURLConnection类的URLConnection = NULL;
        网址URL = NULL;
        的JSONObject对象= NULL;

        尝试
        {
            URL =新的URL(urlString.toString());
            的URLConnection =(HttpURLConnection类)url.openConnection();
            urlConnection.setRequestMethod(GET);
            urlConnection.setDoOutput(真正的);
            urlConnection.setDoInput(真正的);
            urlConnection.connect();
            的InputStream inStream中= NULL;
            inStream中= urlConnection.getInputStream();
            的BufferedReader面包屑=新的BufferedReader(新的InputStreamReader(inStream中));
            字符串温度,反应=;
            而((TEMP = bReader.readLine())!= NULL)
                响应+ =温度;
            bReader.close();
            inStream.close();
            urlConnection.disconnect();
            对象=(JSONObject的)新JSONTokener(响应).nextValue();
        }
        赶上(例外五)
        {
            this.mException = E;
        }

        返回(对象);
    }

    @覆盖
    保护无效onPostExecute(JSONObject的结果)
    {
        super.onPostExecute(结果);

        如果(this.mException!= NULL)
            ErrorHelper.report(this.mException,错误#NearbySearchRequest);
    }
}
 

解决方案

您使用的HTTP引擎似乎是最好的选择。其实任何其他3-第三方引擎或者基于Apache的,无论是在HttpURLConnection的。我preFER使用春季为Android 的作为API提供了一个抽象通过HTTP引擎,你真的不需要怎么在意什么API来使用基于API的水平。或者你也可以使用凌空的 - 一个很时髦的库

不过,我会触动你的一些code:

  1. 如果有读取该流是个例外?然后流保持打开,也是连接。所以我建议有一个finally块,其中流和连接,如果你是封闭无论异常与否:

     的HttpURLConnection的URLConnection = NULL;
    网址URL = NULL;
    的JSONObject对象= NULL;
    的InputStream inStream中= NULL;
    尝试 {
        URL =新的URL(urlString.toString());
        的URLConnection =(HttpURLConnection类)url.openConnection();
        urlConnection.setRequestMethod(GET);
        urlConnection.setDoOutput(真正的);
        urlConnection.setDoInput(真正的);
        urlConnection.connect();
        inStream中= urlConnection.getInputStream();
        的BufferedReader面包屑=新的BufferedReader(新的InputStreamReader(inStream中));
        字符串温度,反应=;
        而((TEMP = bReader.readLine())!= NULL){
            响应+ =温度;
        }
        对象=(JSONObject的)新JSONTokener(响应).nextValue();
    }赶上(例外五){
        this.mException = E;
    } 最后 {
        如果(inStream中!= NULL){
            尝试 {
                //这将关闭面包屑以及
                inStream.close();
            }赶上(IOException异常忽略){
            }
        }
        如果(URLConnection的!= NULL){
            urlConnection.disconnect();
        }
    }
     

  2. JSON解析:你使用JSON解析了Android标准的方式,但是这不是最快的,最简单的工作。 GSON 杰克逊是更好地使用。 <一href="http://stackoverflow.com/questions/7935078/performance-and-usability-comparison-of-android-json-libraries">To做一个比较当谈到对JSON解析器,我会去杰克逊。这里是这种比较的另一个SO话题

  3. 不串接这样的字符串作为连接字符串将每次创建另一个字符串。使用 的StringBuilder 代替。

  4. 异常处理(这是无论如何在所有的编程论坛上长期争论主题)。首先,你需要登陆它(使用 登录 类没有 System.out.printXXX )。然后,你需要或者通知用户:要么你敬酒的消息,任你展现一个标签或通知。这一决定取决于用户的情况下,如何相关的是,你正在做电话。

这些都是我在你看到了主题code。

修改我意识到我没有回答这个问题:<?code>是AsyncTask的对后台线程运行的最有效的方式还是应该用别的东西

简短的回答我给的是:如果你应该执行时间短住请求,则的AsyncTask 是完美的。但是,如果你需要得到一些数据并显示它 - 但你不想再担心是否要重新下载,如果屏幕旋转等,我会强烈建议使用<一个href="http://developer.android.com/reference/android/content/AsyncTaskLoader.html"><$c$c>AsyncTaskLoader 装载机 一般。

如果你需要下载一些大的数据,那么无论您使用的<一个href="http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/"><$c$c>IntentService或者,用于重重量的操作,<一href="http://blog.vogella.com/2011/06/14/android-downloadmanager-example/"><$c$c>DownloadManager.

享受编码!

I'm the perfectionist type, I already got web API calls working fine with Google Places API (just as an example), but I feel it's sometimes slow or maybe I'm not doing it right. Some blogs are saying I should use AndroidHttpClient, but I'm not, should I ?

The web API calls i'm using return json and I don't run them on the UI thread, hence using AsyncTask (is AsyncTask the most efficient way to run on background thread or should I use something else ?)

Please see my code and tell me how could it be more efficient in anyway

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

解决方案

The Http engine you're using seems the best choice. Actually any other 3-rd party engines are based either on Apache, either on HttpUrlConnection. I prefer to use Spring for Android as that API provide an abstraction over Http Engine and you don't really need to care how about what API to use based on API level. Or you can use Volley - a very fashionable library.

I would touch however some of your code:

  1. What if there is an exception while reading the stream? Then the stream remains open and also the connection. So I would suggest to have a finally block where the streams and connection is closed no matter if you get an exception or not:

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

  2. JSON parsing: you're using the Android standard way of parsing JSON, but that's not the fastest and easiest to work with. GSON and Jackson are better to use. To make a comparison when it comes for JSON parsers, I would go for Jackson. Here's another SO topic on this comparison.

  3. Don't concatenate strings like that as concatenating strings will create each time another string. Use a StringBuilder instead.

  4. Exception handling (this is anyway a long-debate subject in all programming forums). First of all you have to log it (Use Log class not System.out.printXXX). Then you need to either inform the user: either you toast a message, either you show a label or notification. The decision depends on the user case and how relevant is the call you're making.

These are the topics I see in you code.

EDIT I realize I didn't answer this: is AsyncTask the most efficient way to run on background thread or should I use something else?

The short answer I would give is: if you're supposed to perform a short time lived request, then AsyncTask is perfect. However, if you need to get some data and display it - but you don't want to worry about whether to download again if the screen is rotated and so on, I would strongly recommend using an AsyncTaskLoader and Loaders in general.

If you need to download some big data, then either you use an IntentService or, for heavy-weight operations, DownloadManager.

Enjoy coding!

这篇关于什么是Android上最有效的方式来调用返回一个JSON响应HTTP的Web API调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆