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

我是完美主义者types,我已经使用Google Places API工作得很好,但是我感觉有时很慢,或者我做的不对。 有些博客说我应该使用AndroidHttpClient,但我不是,应该吗?

Web API调用我使用返回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"); } } 

Solutions Collecting From Web of "Android上调用返回JSON响应的HTTP Web API调用最有效的方法是什么?"

你使用的Http引擎似乎是最好的select。 其实任何其他的第三方引擎都是基于Apache,或者是HttpUrlConnection。 我更喜欢使用Android for Spring,因为这个API提供了一个关于Http Engine的抽象,而且您并不需要关心如何根据API级别来使用API​​。 或者你可以使用Volley – 一个非常时尚的图书馆。

我会接触一些你的代码:

  1. 如果在阅读stream时出现exception,该怎么办? 然后stream保持打开,也是连接。 所以我会build议有一个终止块,其中的stream和连接是封闭的,不pipe你是否遇到exception:

     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. JSONparsing:你正在使用Android标准的parsingJSON的方式,但这不是最快和最简单的工作。 GSON和jackson更好用。 为了比较一下JSONparsing器,我会selectJackson。 这是另一个关于这个比较的SO主题 。

  3. 不要像这样连接string,因为连接string会每次创build另一个string。 改用StringBuilder

  4. exception处理(无论如何,这是所有编程论坛中的一个长期争论话题)。 首先你必须logging它(使用Log类而不是System.out.printXXX )。 然后,您需要通知用户:要么给您留言,要么显示标签或通知。 这个决定取决于用户的情况,以及你所做的呼叫有多相关。

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

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

我会给出的简短的答案是:如果你应该执行一个短暂的时间请求,那么AsyncTask是完美的。 但是,如果您需要获取一些数据并显示它,但是您不必担心是否在屏幕旋转等情况下再次下载,我强烈推荐使用AsyncTaskLoaderLoaders

如果您需要下载一些大数据,那么您可以使用IntentService或者对于重量级操作DownloadManager

享受编码!

——为您的项目创build一个服务处理程序类——–

 public class ServiceHandler { static String response = null; public final static int GET = 1; public final static int POST = 2; public ServiceHandler() { } /* * Making service call * @url - url to make request * @method - http request method * */ public String makeServiceCall(String url, int method) { return this.makeServiceCall(url, method, null); } /* * Making service call * @url - url to make request * @method - http request method * @params - http request params * */ public String makeServiceCall(String url, int method, List<NameValuePair> params) { try { // http client DefaultHttpClient httpClient = new DefaultHttpClient(); HttpEntity httpEntity = null; HttpResponse httpResponse = null; // Checking http request method type if (method == POST) { Log.e("in POST","in POST"); HttpPost httpPost = new HttpPost(url); // adding post params if (params != null) { Log.e("in POST params","in POST params"); httpPost.setEntity(new UrlEncodedFormEntity(params)); } Log.e("url in post service",url); httpResponse = httpClient.execute(httpPost); } else if (method == GET) { // appending params to url Log.e("in GET","in GET"); if (params != null) { Log.e("in GET params","in GET params"); String paramString = URLEncodedUtils .format(params, "utf-8"); url += "?" + paramString; } Log.e("url in get service",url); HttpGet httpGet = new HttpGet(url); httpResponse = httpClient.execute(httpGet); } httpEntity = httpResponse.getEntity(); response = EntityUtils.toString(httpEntity); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return response; } public String makeServiceCallIMAGE(String url, int method, List<NameValuePair> params) { try { // http client DefaultHttpClient httpClient = new DefaultHttpClient(); HttpEntity httpEntity = null; HttpResponse httpResponse = null; // Checking http request method type if (method == POST) { HttpPost httpPost = new HttpPost(url); // adding post params if (params != null) { httpPost.setEntity(new UrlEncodedFormEntity(params)); } httpResponse = httpClient.execute(httpPost); } else if (method == GET) { // appending params to url if (params != null) { String paramString = URLEncodedUtils .format(params, "utf-8"); url += "?" + paramString; } HttpGet httpGet = new HttpGet(url); httpResponse = httpClient.execute(httpGet); } httpEntity = httpResponse.getEntity(); response = EntityUtils.toString(httpEntity); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return response; } } 

————– AsyncTasklogin——————

 public class Login_Activity extends ActionBarActivity { //Internet Service NetworkConnection nw; ProgressDialog prgDialog; Boolean netConnection = false; // //Login API String loginURL ="url"; // @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); nw = new NetworkConnection(getApplicationContext()); prgDialog = new ProgressDialog(this); // Set Cancelable as False prgDialog.setCancelable(false); new LoginOperation().execute(); } private class LoginOperation extends AsyncTask<String, Void, Void> { String status, message; @Override protected void onPreExecute() { // Set Progress Dialog Text prgDialog.setMessage("Logging..."); prgDialog.show(); } @Override protected Void doInBackground(String... urls) { if(nw.isConnectingToInternet() == true) { try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("method", "ClientesLogin")); nameValuePairs.add(new BasicNameValuePair("Email", str_Email)); nameValuePairs.add(new BasicNameValuePair("Senha", str_Password)); ServiceHandler sh = new ServiceHandler(); String response = sh.makeServiceCall(loginURL, ServiceHandler.GET, nameValuePairs); Log.e("response", response); JSONObject js = new JSONObject(response); status = js.getString("status"); Log.e("status",status); if(status.contains("Fail")) { message = js.getString("message"); } /*else { JSONObject jslogin=js.getJSONObject("user_list"); for (int i = 0; i < jslogin.length(); i++) { } }*/ }catch(Exception ex){ } netConnection = true; }else { netConnection = false; } return null; } @Override protected void onPostExecute(Void result) { prgDialog.dismiss(); if(netConnection == false) { Toast toast = Toast.makeText(getApplicationContext(),"Internet is not available. Please turn on and try again.", Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); } else { if(status.contains("Success")) { Toast toast = Toast.makeText(getApplicationContext(), "Login Successful", Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); Intent i=new Intent(Login_Activity.this,home_page_activity.class); startActivity(i); } else{ Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); } } super.onPostExecute(result); } } } 

—————networking连接类———————

 public class NetworkConnection { Context context; public NetworkConnection(Context context){ this.context = context; } public boolean isConnectingToInternet(){ ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivity != null) { NetworkInfo[] info = connectivity.getAllNetworkInfo(); if (info != null) for (int i = 0; i < info.length; i++) if (info[i].getState() == NetworkInfo.State.CONNECTED) { return true; } } return false; } } 

 JSONArray main1 = js.getJSONArray("Test 1"); for (int i = 0; i < main1.length(); i++) { JSONObject jsonObject = main1.getJSONObject(i);