2010-09-09 4 views
2

J'ai une classe (RestClient.java) qui étend AsyncTask: package org.stocktwits.helper;Problème renvoyant un objet à partir d'un AsyncTask

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.JSONException; 
import org.json.JSONObject; 

import android.os.AsyncTask; 
import android.util.Log; 

public class RestClient extends AsyncTask<String, Void, JSONObject>{ 
    public JSONObject jsonObj = null; 
    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 "Praeda". 
    */ 
    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("Praeda",response.getStatusLine().toString()); 

      // Get hold of the response entity 
      HttpEntity entity = response.getEntity(); 

      if (entity != null) { 

       // A Simple JSON Response Read 
       InputStream instream = entity.getContent(); 
       String result= convertStreamToString(instream); 

       // A Simple JSONObject Creation 
       JSONObject json=new JSONObject(result); 

       // Closing the input stream will trigger connection release 
       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; 
    } 

    @Override 
    protected JSONObject doInBackground(String... urls) { 
     return connect(urls[0]); 
    } 

    @Override 
    protected void onPostExecute(JSONObject json) { 
     this.jsonObj = json; 
    } 

    public void setJSONObject(JSONObject jsonFromUI){ 
     this.jsonObj = jsonFromUI; 
    } 

    public JSONObject getJSONObject(){ 
     return this.jsonObj; 
    } 

} 

Je suis en train d'exécuter le AsyncTask sur ma classe principale (Main.java):

RestClient rc = new RestClient(); 
    JSONObject json = new JSONObject(); 
    rc.setJSONObject(json); 
    rc.execute(buildQuery()); 
    json = rc.getJSONObject(); 

//do some stuff with the json object 
try { JSONObject query = json.getJSONObject("query"); 
//... 
} 

JSON est nulle parce qu'elle est appelée avant onPostExecute(). Comment puis-je obtenir mon JSON?

MISE À JOUR: Je dois exécuter ce bloc d'essai dans onPostExecute():

try { 

      JSONObject query = json.getJSONObject("query"); 
      JSONObject results = query.getJSONObject("results"); 

      if (query.getString("count").equals("1")) { // YQL JSON doesn't 
       // return an array for 
       // single quotes 
       JSONObject quote = results.getJSONObject("quote"); 

       Quote myQuote = new Quote(); 
       myQuote.setName(quote.getString("Name")); 
       myQuote.setSymbol(quote.getString("Symbol")); 
       myQuote.setLastTradePriceOnly(quote 
         .getString("LastTradePriceOnly")); 
       myQuote.setChange(quote.getString("Change")); 
       myQuote.setOpen(quote.getString("Open")); 
       myQuote.setMarketCapitalization(quote 
         .getString("MarketCapitalization")); 
       myQuote.setDaysHigh(quote.getString("DaysHigh")); 
       myQuote.setYearHigh(quote.getString("YearHigh")); 
       myQuote.setDaysLow(quote.getString("DaysLow")); 
       myQuote.setYearLow(quote.getString("YearLow")); 
       myQuote.setVolume(quote.getString("Volume")); 
       myQuote.setAverageDailyVolume(quote 
         .getString("AverageDailyVolume")); 
       myQuote.setPeRatio(quote.getString("PERatio")); 
       myQuote.setDividendYield(quote.getString("DividendYield")); 
       myQuote.setPercentChange(quote.getString("PercentChange")); 

       quotesAdapter.add(myQuote);} 

Répondre

2

Je tromperais par suite de doInBackground peut être consommé dans onPostExecute

doInBackground (Params ...), appelée sur le fil de fond immédiatement après sur les finitions PreExecute() d'exécution. Cette étape est utilisée pour effectuer un calcul de fond que peut prendre beaucoup de temps. Les paramètres de la tâche asynchrone sont transmis à cette étape. Le résultat du calcul doit être renvoyé par cette étape et sera renvoyé à la dernière étape. Cette étape peut également utiliser publishProgress (Progress ...) à pour publier une ou plusieurs unités de progression . Ces valeurs sont publiées dans le thread d'interface utilisateur, dans l'étape onProgressUpdate (progression ...).

@Override 

protected void onPostExecute(JSONObject json) { 
// DO stuff here (it's UI thread) 
mJsonFromTheActivity = json; 
} 
+0

disons donc onPostExecute() retourne un JSONObject. Comment puis-je l'appeler de ma classe principale? Puis-je juste dire JSONObject json = rc.onPostExecute() et obtenir l'objet retourné? –

+0

Non, mais vous pouvez l'assigner au membre var depuis votre onPostExecute –

+0

Cela peut ne pas (et n'est probablement pas) le bon moyen, mais une façon de le faire est de déclarer une variable globale, puis dans la méthode onPostExecute, Définissez cette variable sur la variable passée à onPostExecute. par exemple. JSONObject privé jsonObject; ... onPostExecute (JSONObject json) {jsonObject = json; } Je voudrais aussi savoir un meilleur moyen, mais je n'ai pas fait trop de recherche sur ceci pour le moment. – kcoppock

0

execute() retourne toujours le AsyncTask lui-même. L'objet que vous renvoyez de doInBackground() vous est remis dans onPostExecute().

+0

merci pour la clarification. Comment puis-je obtenir le JSONObject de onPostExecute()? –

0

Si vous avez votre AsyncTask en tant que classe interne de votre activité imbriquée, vous pouvez définir une de vos activités variables à la suite de votre AsyncTask

5

Hey Vous pouvez utiliser les auditeurs pour résoudre ce problème. J'ai légèrement modifié le code pour l'utiliser.

package com.insidetip.uob.data; 
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.JSONException; 
import org.json.JSONObject; 

import android.app.ProgressDialog; 
import android.content.Context; 
import android.os.AsyncTask; 
import android.util.Log; 

public class JSONClient extends AsyncTask<String, Void, JSONObject>{ 
    ProgressDialog progressDialog ; 
    GetJSONListener getJSONListener; 
    Context curContext; 
    public JSONClient(Context context, GetJSONListener listener){ 
     this.getJSONListener = listener; 
     curContext = context; 
    } 
    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(); 
    } 


    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("Praeda",response.getStatusLine().toString()); 

      // Get hold of the response entity 
      HttpEntity entity = response.getEntity(); 

      if (entity != null) { 

       // A Simple JSON Response Read 
       InputStream instream = entity.getContent(); 
       String result= convertStreamToString(instream); 

       // A Simple JSONObject Creation 
       JSONObject json=new JSONObject(result); 

       // Closing the input stream will trigger connection release 
       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; 
    } 
    @Override 
    public void onPreExecute() { 
     progressDialog = new ProgressDialog(curContext); 
     progressDialog.setMessage("Loading..Please wait.."); 
     progressDialog.setCancelable(false); 
     progressDialog.setIndeterminate(true); 
     progressDialog.show(); 

    } 

    @Override 
    protected JSONObject doInBackground(String... urls) { 
     return connect(urls[0]); 
    } 

    @Override 
    protected void onPostExecute(JSONObject json) { 
     getJSONListener.onRemoteCallComplete(json); 
     progressDialog.dismiss(); 
    } 
} 

Utilisez dans la classe appelante comme ceci.

JSONClient client = new JSONClient(context, listener); 
    client.execute(URL); 

Ne pas oublier de mettre en œuvre l'auditeur

public interface GetJSONListener { 
    public void onRemoteCallComplete(JSONObject jsonFromNet); 
} 
+0

agréable. J'utilise ceci dans mon projet. Je vous remercie. –

Questions connexes