Autore Topic: problema gestione eccezioni connessione  (Letto 2101 volte)

Offline DX89B

  • Utente junior
  • **
  • Post: 121
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Play Store ID:
    Daniele Bonadiman
  • Sistema operativo:
    Mac OS X 10.6
problema gestione eccezioni connessione
« il: 24 Agosto 2010, 08:50:06 CEST »
0
La mia applicazione utilizza la connessione internet per accedere a dei dati in remoto, faccio una connessione Http per fare una get ti un file json faccio il parsing ecc , nella situazione ottima tutto ok funziona e visualizza ciò che mi serve sotto forma di list , i problemi nascono nei casi particolari.

Manca la connessione , crash
(qui ho provato ad utilizzare )
Codice (Java): [Seleziona]
 public boolean isOnline() {
                ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                return cm.getActiveNetworkInfo().isConnectedOrConnecting();
        }
ma niente all'apertura dell'app mi da invalidTargetException.

Utente errato, crash questo errore si trova  anche si cerca di accedere a contenuti non disponibili, qui ho paura che il software cerchi di creare una lista da struttura dati vuota, proverò a correggere poi modifico

in poche parole c'è un crash ogni volta che viene lanciata un'eccezione dall'HttpClient (almeno credo)  come pensate che vadano gestite queste eccezioni, conoscete qualche utile tutorial per risolvere questo problema??

grazie

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:problema gestione eccezioni connessione
« Risposta #1 il: 24 Agosto 2010, 09:08:09 CEST »
0
Da quanto ne so, ci sono due cose da dire.

Prima di tutto le attività come l'accesso in rete dovrebbero/devono essere eseguite in un thread diverso dall'UI, con un Thread o con un AsyncTask per interndersi. Perchè l'applicazione va in Force Close se il thread dell'UI rimane bloccato per più di 5 secondi.

Seconda cosa, le eccezioni nelle connessioni sono particolarmente importanti da gestire, perchè sono tante le casistiche di errore che si possono verificare. Ora, non so che codice usi per eseguire la connessione (se usi HttpClient o URLConnection o altro), però genericamente la struttura è questa:

Codice (Java): [Seleziona]
         try {

            // connessione HTTP            

         } catch (HttpResponseException e) {
            // gestisce le risposte diverse da HTTP code 200
            Log.w(TAG,"HTTP Response Exception : "+e.toString());
         } catch (Exception e) {
            Log.w(TAG,"Error : "+e.toString());
         }

Prego i più esperti di correggere eventuali inesattezze che ho scritto.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline DX89B

  • Utente junior
  • **
  • Post: 121
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Play Store ID:
    Daniele Bonadiman
  • Sistema operativo:
    Mac OS X 10.6
Re:problema gestione eccezioni connessione
« Risposta #2 il: 24 Agosto 2010, 09:13:45 CEST »
0
grazie per la risposta, si effettivamente nn avevo pensato di eseguire il tutto in un thread separato, cmq utilizzo HttpClient provo a vedere se risolvo in questo modo, comunque aspetterei a mettere risolto che magari (probabilmente incontrerò altri problemi)

Offline DX89B

  • Utente junior
  • **
  • Post: 121
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Play Store ID:
    Daniele Bonadiman
  • Sistema operativo:
    Mac OS X 10.6
Re:problema gestione eccezioni connessione
« Risposta #3 il: 24 Agosto 2010, 09:23:28 CEST »
0
io ho creato una classe chiamata restClient dove svolgo tutte le funzioni relative alla connessione, in pratica devo creare un'altra classe che estende Thread dove faccio le chiamate ai metodi di restClient magari mettendo a video un progres dialog mentre svolgo tali funzioni?
altra cosa il thread principale deve essere messo in sleep fino alla terminazione del thread dove svolgo le get giusto? devo fare una sorta di sincronizzazione?
« Ultima modifica: 24 Agosto 2010, 09:25:28 CEST da DX89B »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:problema gestione eccezioni connessione
« Risposta #4 il: 24 Agosto 2010, 09:27:48 CEST »
+1
grazie per la risposta, si effettivamente nn avevo pensato di eseguire il tutto in un thread separato, cmq utilizzo HttpClient provo a vedere se risolvo in questo modo, comunque aspetterei a mettere risolto che magari (probabilmente incontrerò altri problemi)

Ok, se usi HttpClient, ti copio il blocco che ho usato in alcune mie prove, se posti anche il tuo confrontiamo le soluzioni. Tieni conto che io lo uso in un AsyncTask.

Codice (Java): [Seleziona]
         try {
           
            URI uri;
            uri = new URI("http",null,"www.mioserver.com",-1,"/folder","id="+params[0],null);
            HttpUriRequest get = new HttpGet(uri);
            client = new DefaultHttpClient();
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            result = client.execute(get,responseHandler);

         } catch (HttpResponseException e) {
            // gestisce le risposte diverse da HTTP code 200
            Log.w(TAG,"HTTP Response Exception : "+e.toString());
         } catch (Exception e) {
            Log.w(TAG,"Error : "+e.toString());
         } finally {
            if (client != null) client.getConnectionManager().shutdown();
         }
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline MarcoDuff

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1073
  • Respect: +202
    • Google+
    • marcoduff
    • Mostra profilo
    • MarcoDuff's Blog
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    MarcoDuff
  • Sistema operativo:
    Windows 7
Re:problema gestione eccezioni connessione
« Risposta #5 il: 24 Agosto 2010, 09:32:24 CEST »
0
Le connessioni devono essere gestite in thread diversi dal principale (quello dell'Activity per intenderci).

Non hai bisogno di mettere in sleep il therad principale (anzi sarebbe un errore!). Se vuoi bloccare le interazioni con la UI mentre effettui la connessione metti una ProgressDialog.

Ciao!

Offline DX89B

  • Utente junior
  • **
  • Post: 121
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
  • Play Store ID:
    Daniele Bonadiman
  • Sistema operativo:
    Mac OS X 10.6
Re:problema gestione eccezioni connessione
« Risposta #6 il: 24 Agosto 2010, 09:37:53 CEST »
0
allora , la mia classe restClient era stata presa da internet e poi in parte modificata :P

essendo che gestisco solo Json Object nell'activity la restClient lavora solo con Json ti posto questa classe
come ti ho detto le eccezioni non sono gestite a dovere :)
Codice (Java): [Seleziona]
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
 
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
 
import android.content.Context;
import android.net.ConnectivityManager;
import android.util.Log;

 
public class RestClient {
 
    private static String convertStreamToString(InputStream is) {
        /*
         * To convert the InputStream to String we use the BufferedReader.readLine()
         * method. We iterate until the BufferedReader return null which means
         * there's no more data to read. Each line will appended to a StringBuilder
         * and returned as String.
         */

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
 
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
 
    /* This is a test function which will connects to a given
     * rest service and prints it's response to Android Log with
     * labels "logrest".
     */

    public static JSONObject connect(String url)
    {
 
        HttpClient httpclient = new DefaultHttpClient();
 
        // Prepare a request object
        HttpGet httpget = new HttpGet(url);
 
        // Execute the request
        HttpResponse response;
        try {
            response = httpclient.execute(httpget);
            // Examine the response status
            Log.i("logrest",response.getStatusLine().toString());
 
            // Get hold of the response entity
            HttpEntity entity = response.getEntity();
            // If the response does not enclose an entity, there is no need
            // to worry about connection release
 
            if (entity != null) {
 
                // A Simple JSON Response Read
                InputStream instream = entity.getContent();
                String result= convertStreamToString(instream);
                Log.i("logrest",result);
 
                // A Simple JSONObject Creation
                JSONObject json=new JSONObject(result);
                Log.i("logrest","<jsonobject>\n"+json.toString()+"\n</jsonobject>");
 
                // A Simple JSONObject Parsing
                JSONArray nameArray=json.names();
                JSONArray valArray=json.toJSONArray(nameArray);
                for(int i=0;i<valArray.length();i++)
                {
                    Log.i("logrest","<jsonname"+i+">\n"+nameArray.getString(i)+"\n</jsonname"+i+">\n"
                            +"<jsonvalue"+i+">\n"+valArray.getString(i)+"\n</jsonvalue"+i+">");
                }
 
                instream.close();
                return json;
            }
 
 
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
   
   
 
}

questo client viene chiamato nell'activity in questo modo
Codice (Java): [Seleziona]
RestClient client = new RestClient();
 JSONObject json  = client.connect("www.myurl.it");

non fare troppo caso a codice sporco o mal commentato, sono solo test , il progetto va riscritto quasi completamente :)




Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:problema gestione eccezioni connessione
« Risposta #7 il: 24 Agosto 2010, 09:56:49 CEST »
0
Se non hai esigenze particolari di gestione dei della connessione potresti semplificare pesantemente il codice. Il fatto è che usando HttpResponse per gestire la risposta si ha molta flessibilità, però devi gestire a mano tutti i vari codici di risposta e convertire lo stream in String.

Puoi eliminare tutto mettendo le due righe che vedi nel mio esempio, che automaticamente gestiscono tutto il protocollo HTTP e restituiscono una String. Gli errori si gestiscono nell'eccezione che vedi poco sotto.

Codice (Java): [Seleziona]
String result;
...
ResponseHandler<String> responseHandler = new BasicResponseHandler();
result = client.execute(get,responseHandler);

Per come impostare l'AsyncTask, c'è l'utilissimo Tutorial di Qlimax ([facile] Aggiornare la UI da una Thread - Android Developers Italia), che ho usato personalmente per fare interrogazioni ad un server per ottenere un feed XML. Se ho un po' di tempo pulisco il codice e lo posto in un thread a parte.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store