posta l'intero codice della classe asynctask ed il metodo che chiama l'asynctask
posta l'intero codice della classe asynctask ed il metodo che chiama l'asynctask
PostReq.java -->
E questo è il metodo che si trova nell'activityMain, eseguito quando l'utente clicca sul button -->codice:class PostReq extends AsyncTask<List<NameValuePair>, Integer, String>{ String contenuto=""; @Override public String doInBackground(List<NameValuePair>... params) { //TODO Auto-generated method stub postData(params[0]); return contenuto; } protected void onPostExecute(String result){ //Toast.makeText(null, "command sent", Toast.LENGTH_LONG).show(); } public void postData(List<NameValuePair> dict) { String url= dict.get(0).getValue(); dict.remove(0); HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); try { httppost.setEntity(new UrlEncodedFormEntity(dict)); HttpResponse response = httpclient.execute(httppost); contenuto= inputStreamToString(response.getEntity().getContent()); System.out.println("risposta "+ contenuto); } catch (ClientProtocolException e) { System.out.println("risposta errorecl"); //TODO Auto-generated catch block } catch (IOException e) { System.out.println("risposta erroreio"); //TODO Auto-generated catch block } } private String inputStreamToString(InputStream is) { String s = ""; String line = ""; BufferedReader rd = new BufferedReader(new InputStreamReader(is)); try { while ((line = rd.readLine()) != null) { s += line; } } catch (IOException e) { e.printStackTrace(); } return s; } }
Ho tolto tutti gli import dalla classe PostReq, basta premere SHIFT + CTRL + O im eclipse per importarli automaticamentecodice:public void btnWeb_Click(View view){ String url="http://192.168.1.14/test/index.php"; List<NameValuePair> dict = new ArrayList<NameValuePair>(); dict.add(new BasicNameValuePair("url",url)); dict.add(new BasicNameValuePair("id", "contDelPost")); PostReq postreq= new PostReq(); postreq.execute(dict); String result=""; while(result==""){ result= postreq.contenuto;} System.out.println(result); }
Ultima modifica di jejpeeg; 05-06-13 alle 18:21
Caro mio mi sa che devi ancora capire cosa c'è scritto nella documentazione
Questa implementazione è fatta a botto e quindi possono esserci degli errori di battitura e deve essere ottimizzata ma in linea di massima è così
codice:public class PostReq extends AsyncTask<NameValuePair, Void, String> { private MainActivity ma; private String url; private String contenuto = null; private HttpClient httpClient; private HttpPost httpPost; public PostReq(MainActivity ma, String url) { this.ma = ma; this.url = url; } @Override public String doInBackground(NameValuePair... params) { try { // imposto i parametri che NON SONO FILE httpPost.setEntity(new UrlEncodedFormEntity(Arrays.asList(params))); // effettuo la richiesta ed ottengo la risposta HttpResponse response = httpClient.execute(httpPost); // TODO Cambiati tu poi le cose in base agli status code che ottieni // se ho una risposta ok if (response.getStatusLine().getStatusCode() == 200) { // contenuto = inputStreamToString(response.getEntity().getContent()); } else { contenuto = "Capitato un errore " + response.getStatusLine().getStatusCode(); } } catch (ClientProtocolException e) { System.err.println("Errore ClientProtocolException"); e.printStackTrace(); } catch (IOException e) { System.err.println("Errore IOException"); e.printStackTrace(); } // restituisco il risultato return contenuto; } protected void onPostExecute(String result) { Toast.makeText(ma, "Risposta: " + result, Toast.LENGTH_LONG).show(); // TODO Qua ti fai i compitini a inserire la tua risposta nell'activity } protected void onPreExecute() { httpClient = new DefaultHttpClient(); httpPost = new HttpPost(url); } private String inputStreamToString(InputStream is) { StringBuilder s = new StringBuilder(); BufferedReader rd = new BufferedReader(new InputStreamReader(is)); String line; try { while ((line = rd.readLine()) != null) { s.append(line).append("\n"); } } catch (IOException e) { e.printStackTrace(); } return s.toString(); } }codice:public void btnWeb_Click(View view) { String url = "http://192.168.1.14/test/index.php"; PostReq postreq = new PostReq(this, url); postreq.execute(new BasicNameValuePair("id", "contDelPost")); }
ehmm.. cioè? la mia classe PostReq funzionava! Non è mica quella che va modificata..
il problema è nel meotodo
che non attende asincronicamente la risposta del server e per farlo devo usare un while che blocca tutto finche il server non ha risposto.. ho bisogno che l'oggetto postreq una volta eseguito restituisca il contenuto ottenuto dal server come stringa nel mainActivity senza bloccare tutto........codice:public void btnWeb_Click(View view){ String url="http://192.168.1.14/test/index.php"; List<NameValuePair> dict = new ArrayList<NameValuePair>(); dict.add(new BasicNameValuePair("url",url)); dict.add(new BasicNameValuePair("id", "contDelPost")); PostReq postreq= new PostReq(); postreq.execute(dict); String result=""; while(result==""){ result= postreq.contenuto;} System.out.println(result); }
Non entro nel merito del codice che hai scritto, dando per scontato che sia tutto corretto...
Come metodo da seguire basta seguire queste regole:
1) la prima parte (quella che crea e lancia l'AsyncTask) mi sembra corretta
2) i valori che devi ricavare dal server li ricavi nel metodo doInBackground o da altri metodi richiamati dallo stesso (cosa che mi sembra hai fatto). Tutto ciò è eseguito in un thread distinto;
3) da doInBackground passi il tuo risultato a onPostExecute con return
4) onPostExecute viene eseguito nel thread di esecuzione della GUI. Quindi da lì potresti anche modificare direttamente la tua interfaccia visualizzando il risultato in qualche componente o aggiornando il valore delle tue variabili.
NB. Se la classe che estende AsyncTask (PostReq) è una classe innestata nella classe principale, da essa dovrebbe essere possibile accedere direttamente a tutte le variabili di istanza della classe esterna. Quindi puoi impostare direttamente il valore delle tue variabili.
Se invece PostReq è una top level class (come sembrerebbe nel tuo caso), allora per modificare il valore delle tue variabili nella classe di partenza o le dichiari pubbliche (metodo sconsigliato), oppure passi i valori tramite un interfaccia. Io userei una classe innestata, che è il metodo più semplice.
In ogni caso non serve alcun loop nel metodo di partenza.
Nel tuo caso secondo me l'errore è che nel metodo di partenza cerchi di ricavare il risultato prima ancora che questo sia stato recuperato dal tuo AsyncTask.
La logica è che è AsyncTask che comunica il risultato alla classe di partenza quando lo ha ricavato, come detto sopra; non è la classe di partenza che continua ad interrogare l'AsyncTask fino a quando non è stato ottenuto il risultato.
Spero di essere stato chiaro.
Ultima modifica di iClaude76; 05-06-13 alle 21:08
Personal Budget app:
https://play.google.com/store/apps/d...personalbudget
LinkedIn:
https://www.linkedin.com/profile/vie...ve_tab_profile
jejpeeg (06-06-13)
Ok, grazie
Anche se la classe innestata è proprio quello che volevo evitare.. perchè vorrebbe dire che se ho 3 o 4 Activity che generano richieste post, dovrei riscrivere la classe anche in quelle activity. E' per questo che cercavo qualcosa come AWAIT che ho in c#
Ultima modifica di jejpeeg; 06-06-13 alle 14:24