Autore Topic: Connessione al server e parsing JSON con AsyncTask  (Letto 680 volte)

Offline Steve46

  • Nuovo arrivato
  • *
  • Post: 3
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    LG G2
  • Sistema operativo:
    Mac OSX 10.9
Connessione al server e parsing JSON con AsyncTask
« il: 19 Luglio 2014, 17:41:16 CEST »
0
Comincio col dire che avrò già letto almeno una ventina di guide ma nessuna ha ancora risolto i miei dubbi e/o si applica bene al mio caso.
Ho un classe JSONParser così composta:

Codice (Java): [Seleziona]
public class JSONParser {
 
    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";
    private static String URL = "http://10.0.2.2/android_login_api/"; //"http://192.168.1.102/android_login_api/"
 
    // constructor
    public JSONParser(){
    }
   
  public JSONObject getJSONFromUrl(List<NameValuePair> params) {
        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(URL);
            httpPost.setEntity(new UrlEncodedFormEntity(params));
 
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();
 
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "n");
            }
               
            is.close();
            json = sb.toString();
            Log.e("JSON", json);
               
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }
 
        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);            
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }
 
        // return JSON String
        return jObj;
 
    }
   
}

e poi ho una classe UserFunctions che svolge determinate funzioni che richiamano il metodo JSONParser :

Codice (Java): [Seleziona]
public class UserFunctions{
     
    private JSONParser jsonParser;
     
    private static String login_tag = "login";
    private static String register_tag = "register";
    private static String new_reservation_tag = "reservation";
    private static String get_reservation_tag = "get_reservation";
     
    // constructor
    public UserFunctions(){
        jsonParser = new JSONParser();
    }
     
    /**
     * function make Login Request
     * @param email
     * @param password
     * */

    public JSONObject loginUser(String email, String password){
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("tag", login_tag));
        params.add(new BasicNameValuePair("email", email));
        params.add(new BasicNameValuePair("password", password));
        JSONObject json = jsonParser.getJSONFromUrl(params);
        //Log.e("JSON", json.toString());
        return json;
    }
     
    /**
     * function make Registration Request
     * @param name
     * @param email
     * @param password
     * */

    public JSONObject registerUser(String name, String email, String password){
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("tag", register_tag));
        params.add(new BasicNameValuePair("name", name));
        params.add(new BasicNameValuePair("email", email));
        params.add(new BasicNameValuePair("password", password));
         
        // getting JSON Object
        JSONObject json = jsonParser.getJSONFromUrl(params);  
        return json;
    }
   
    /**
     * function make new Reservation
     * @param email
     * @param attivita
     * @param data
     * @param ora
     * */

    public JSONObject newReservation(String email, String attivita, String data, String ora){
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        //String data_string = data.toString();
        params.add(new BasicNameValuePair("tag", new_reservation_tag));
        params.add(new BasicNameValuePair("email", email));
        params.add(new BasicNameValuePair("attivita", attivita));
        params.add(new BasicNameValuePair("data", data));
        params.add(new BasicNameValuePair("ora", ora));
        JSONObject json = jsonParser.getJSONFromUrl(params);
        //Log.e("JSON", json.toString());
        return json;
    }
   
    /**
     * function get Reservation
     * @param email
     * */

    public JSONObject getReservation(String email){
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        //String data_string = data.toString();
        params.add(new BasicNameValuePair("tag", get_reservation_tag));
        params.add(new BasicNameValuePair("email", email));
        JSONObject json = jsonParser.getJSONFromUrl(params);
        //Log.e("JSON", json.toString());
        return json;
    }
}

Dopodichè ovviamente ho anche delle altre classi che accedono alle funzioni della classe UserFunctions, posto un pezzo di codice dell'activity per la registrazione:

Codice (Java): [Seleziona]
// Register Button Click event
        btnRegister.setOnClickListener(new View.OnClickListener() {        
            public void onClick(View view) {
                String name = inputFullName.getText().toString();
                String email = inputEmail.getText().toString();
                String password = inputPassword.getText().toString();
                UserFunctions userFunction = new UserFunctions();
               
                if(!name.contentEquals("") && !email.contentEquals("") && !password.contentEquals("")){
                        if(password.length() > 5){
                JSONObject json = userFunction.registerUser(name, email, password);
                 
                // check for registration response
                try {
                    if (json.getString(KEY_SUCCESS) != null) {
                        registerErrorMsg.setText("");
                        String res = json.getString(KEY_SUCCESS);
                        if(Integer.parseInt(res) == 1){
                            // user successfully registered
                            // Store user details in SQLite Database
                            DatabaseHandler db = new DatabaseHandler(getApplicationContext());
                            JSONObject json_user = json.getJSONObject("user");
                             
                            // Clear all previous data in database
                            userFunction.logoutUser(getApplicationContext());
                            db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));                        
                            // Launch Dashboard Screen
                            Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);
                            // Close all views before launching Dashboard
                            dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(dashboard);
                            // Close Registration Screen
                            finish();
                        }else if (json.getString(KEY_ERROR) != null) {
                                registerErrorMsg.setText("");
                                String err = json.getString(KEY_ERROR);
                                if (Integer.parseInt(err) == 2) {
                                        // Email already existing
                                        registerErrorMsg.setText("Email già esistente");
                                } else {
                            // Error in registration
                            registerErrorMsg.setText("Si è verificato un errore durante la registrazione");
                        }
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();

                }
                        } else {
                                // password too short
                                registerErrorMsg.setText("Inserisci una password di almeno 6 caratteri");
                        }
            } else {
                // missing info
                registerErrorMsg.setText("Devi completare tutti e tre i campi");
            }
            }
        });

Non so più dove sbattere la testa per capire come e dove sia meglio implementare questo benedetto AsyncTask, come accedere ai valori che ritorna (ammesso che gliene si faccia ritornare qualcuno).
Sareste così gentili da darmi una spiegazione comprensibile di come implementarlo e inserendolo nel codice da me postato?
Non so se sia conveniente eliminare il metodo getJSONFromUrl e mettere tutto dentro doInBackground, oppure lasciare tutto com'è e creare un async task nuovo ogni volta che uso il JSONParser.....sto impazzendo!
Vi ringrazio anticipatamente!!

Post unito: 20 Luglio 2014, 13:28:46 CEST
Nessuno che sappia qualcosa?!
« Ultima modifica: 20 Luglio 2014, 13:28:56 CEST da Steve46, Reason: Merged DoublePost »

Offline Fullydroid

  • Nuovo arrivato
  • *
  • Post: 34
  • Respect: +1
    • Mostra profilo
Re:Connessione al server e parsing JSON con AsyncTask
« Risposta #1 il: 22 Luglio 2014, 09:11:09 CEST »
0
Ciao,
sto anch'io programmando in questo periodo un applicazione che comunichi col server tramite il json.
Ho guardato il tuo codice e sinceramente io imposterei la cosa diversamente.

Ti posso postare uno pseudo codice con asyncTask cosi ti fai un idea.

La mia idea e stata di far fare tutto al task nel metodo doInBackGround(..) perchè ad esempio per il login è inutile bloccare il Mainthread dell'applicazione in attesa che finisca il Task.

Codice: [Seleziona]

public class SecurityToken extends AsyncTask<String, Void, ConcurrentHashMap<String, String>> {
   ProgressDialog progressDialog;
   private String name = "", pass = "";
   private Context context;

   public SecurityToken(String name, String pass, Context c) {
      super();
      this.name = name;
      this.pass = pass;
      this.context = c;
   }

   @Override
   protected void onPreExecute() {

      progressDialog = ProgressDialog.show(context,"testo","testo", true);

      // do initialization of required objects objects here
   };

   @Override
   protected ConcurrentHashMap<String, String> doInBackground(String... url) {
      String mail = "mail"; //quello che vuoi
      String pwd = "pwd";//idem cm sopra
      HttpClient httpclient = new DefaultHttpClient();
      HttpPost httppost = new HttpPost(url[0]);
      String jsonString = "";
      try {

         APIJSON.JSONObject holder = new APIJSON.JSONObject();
         try {
            holder.put("App_Login", this.name);
            holder.put("App_Password", pass);

         } catch (APIJSON.JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }

         // passes the results to a string builder/entity
         StringEntity se = new StringEntity(holder.toString());
         httppost.setEntity(se);
         httppost.setHeader("Content-type", "application/json");
         // Execute HTTP Post Request
         HttpResponse response = httpclient.execute(httppost);
         if (response != null)
            jsonString = EntityUtils.toString(response.getEntity());

      } catch (ClientProtocolException e) {

      } catch (IOException e) {
      }
      /*** Parsifico risposta ***/
      JSONObject jsonResponse = null;
      try {
         jsonResponse = new JSONObject(jsonString);
      } catch (JSONException e1) {
         // TODO Auto-generated catch block
         e1.printStackTrace();
      }

     //puoi accedere alla oggetto jsonresponse con gli appositi metodi .get(str).
      return toMainThread;
   }

   /**
    * Il Metodo doInBackground quando finito risponde direttamente la stringa
    * Token a questo metodo.
    *
    */
   @Override
   protected void onPostExecute(ConcurrentHashMap<String, String> Token) {
      super.onPostExecute(Token);
//qui codice quando il task è terminato.
 
      progressDialog.dismiss();

   }
}




Ti chiedo scusa se ci sono delle parentesi errate ma ho tolto un bel po di codice che a te non servirebbe..

quando chiami il task:

Codice: [Seleziona]
...
new SecurityApiTokenTask("xxx", "xxx",getActivity()).execute(//i parametri dell'AsynTaskpassi);
..

Ciao, spero di esserti stato utile!