Quel est le moyen le plus efficace sur Android pour appeler des appels D'API Web HTTP qui renvoient une réponse JSON?

je suis le type perfectionniste, j'ai déjà des appels D'API web qui fonctionnent bien avec L'API Googlesplaces (juste à titre d'exemple), mais je sens que c'est parfois lent ou peut-être que je ne le fais pas correctement. Certains blogs disent que je devrais utiliser AndroidHttpClient, mais je ne le suis pas, devrais-je ?

l'API web appelle que j'utilise return json et que je ne les exécute pas sur le thread UI, donc en utilisant AsyncTask (est-ce que AsyncTask est le moyen le plus efficace d'exécuter sur le thread background ou devrais-je utiliser autre chose ?)

s'il vous Plaît voir mon code et me dire comment pourrait-il être plus efficace dans de toute façon

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");
    }
}
37
demandé sur gunar 2013-09-27 16:02:18

2 réponses

le moteur Http que vous utilisez semble le meilleur choix. En fait, tous les autres moteurs de partie 3-rd sont basés soit sur Apache, soit sur HttpUrlConnection. Je préfère utiliser Spring pour Android car cette API fournit une abstraction sur le moteur Http et vous n'avez pas vraiment besoin de se soucier de ce que L'API à utiliser basé sur le niveau D'API. Ou vous pouvez utiliser Volley - une bibliothèque très à la mode.

je toucherais cependant certains de votre code:

  1. que se passe-t-il s'il y a une exception à la lecture du ruisseau? Puis le ruisseau reste ouvert et aussi la connexion. Je suggère donc d'avoir un bloc final où les flux et la connexion sont fermés peu importe si vous obtenez une exception ou non:

    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: vous utilisez L'Android standard way of parsing JSON, mais ce n'est pas le plus rapide et plus facile à travailler avec. GSON et Jackson sont mieux à utiliser. pour faire une comparaison quand il s'agit de JSON parsers, je dirais Jackson. Voici un autre sujet SO sur cette comparaison.

  3. ne concaténez pas les chaînes comme ça car les chaînes concaténantes créeront à chaque fois une autre chaîne. Utilisez plutôt un StringBuilder .

  4. gestion des exceptions (il s'agit de toute façon d'un sujet de long débat dans tous les forums de programmation). Tout d'abord, vous devez le log (utilisez Log Classe pas System.out.printXXX ). Ensuite, vous devez en informer l'utilisateur: soit vous toast un message, soit vous montrer l'étiquette ou de la notification. La décision dépend du cas de l'utilisateur et de la pertinence de l'appel que vous faites.

ce sont les des sujets que je vois dans votre code.

MODIFIER je me rends compte que je n'ai pas répondu ceci: is AsyncTask the most efficient way to run on background thread or should I use something else?

la réponse courte que je donnerais est: si vous êtes censé exécuter une requête de courte durée, alors AsyncTask est parfait. Cependant, si vous avez besoin d'obtenir quelques données et de l'afficher - mais vous ne voulez pas vous soucier de savoir si TÉLÉCHARGER à nouveau si l'écran est tourné et ainsi de suite, je recommande fortement d'utiliser un AsyncTaskLoader et Loaders en général.

si vous avez besoin de télécharger des données volumineuses, alors vous pouvez utiliser un IntentService ou, pour les opérations lourdes, DownloadManager .

profitez du codage!

42
répondu gunar 2017-05-23 12:34:11

------ créer une classe Service Handler pour votre projet--------

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

--------------AsyncTask Pour La Connexion------------------

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

---------------Connexion Réseau de classe---------------------

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);
6
répondu Nikunj Desai 2016-11-09 13:39:00