2012-02-14 19 views
16

Utrzymam to tak proste, jak to tylko możliwe.Jak mogę pobrać dane z AsyncTasks doInBackground()?

Mam metodę w mojej warstwie kontrolnej, która używa klasy CallServiceTask, która rozszerza AsyncTask. Podczas wywoływania nowego CallServiceTask().execute(parameters) Jak mogę odzyskać dane zwrócone z doInBackground? Wszystkie samouczki, które znalazłem, używają klasy, która rozszerza się AsyncTask bezpośrednio z ich Activity.
Mój problem jest nieco bardziej skomplikowany.
Wszystko, czego chcę, to pobranie Object[] zwróconej przez doInBackground i ustawienie jej na prywatnych członków danych mojej klasy RestClient.

CallServiceTask wygląda następująco:

private class CallServiceTask extends AsyncTask<Object, Void, Object[]> 
{ 

    protected Object[] doInBackground(Object... params) 
    { 
     HttpUriRequest req = (HttpUriRequest) params[0]; 
     String url = (String) params[1]; 

     return executeRequest(req, url); 
    } 
} 

A moja klasa RestClient wygląda następująco:

public class RestClient 
{ 

private ArrayList <NameValuePair> params; 
private ArrayList <NameValuePair> headers; 

private JSONObject jsonData; 

private Object[] rtnData; 

private String url; 

private boolean connError; 

public int getResponseCode() { 
    return responseCode; 
} 

/** 
* 
* @return the result of whether the login was successful by looking at the response parameter of the JSON object. 
*/ 
public Boolean DidLoginSucceed() 
{ 
    // Will Crash on socket error 
     return ((JSONObject) rtnData[0]).optBoolean("response"); 
} 

public String GetToken() 
{ 
    return jsonData.optString("token"); 
} 

public RestClient(String url) 
{ 
    this.url = url; 
    params = new ArrayList<NameValuePair>(); 
    headers = new ArrayList<NameValuePair>(); 
    rtnData = new Object[]{ new JSONObject() , Boolean.TRUE }; 
} 

public void AddParam(String name, String value) 
{ 
    params.add(new BasicNameValuePair(name, value)); 
} 

public void AddHeader(String name, String value) 
{ 
    headers.add(new BasicNameValuePair(name, value)); 
} 

/** 
* This method will execute, call the service and instantiate the JSON Object through executeRequest(). 
* 
* @param method an enum defining which method you wish to execute. 
* @throws Exception 
*/ 
public void ExecuteCall(RequestMethod method) throws Exception 
{ 
    Object[] parameters = new Object[]{ new HttpGet() , new String("") }; 
    switch(method) { 
     case GET: 
     { 
      //add parameters 
      String combinedParams = ""; 
      if(!params.isEmpty()){ 
       combinedParams += "?"; 
       for(NameValuePair p : params) 
       { 
        String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue()); 
        if(combinedParams.length() > 1) 
        { 
         combinedParams += "&" + paramString; 
        } 
        else 
        { 
         combinedParams += paramString; 
        } 
       } 
      } 

      HttpGet request = new HttpGet(url + combinedParams); 

      //add headers 
      for(NameValuePair h : headers) 
      { 
       request.addHeader(h.getName(), h.getValue()); 
      } 
      parameters[0] = request; 
      parameters[1] = url; 

      new CallServiceTask().execute(parameters); 

      jsonData = ((JSONObject) rtnData[0]).optJSONObject("data"); 
      connError = (Boolean) rtnData[1]; 
      break; 

     } 
     case POST: 
     { 
      HttpPost request = new HttpPost(url); 

      //add headers 
      for(NameValuePair h : headers) 
      { 
       request.addHeader(h.getName(), h.getValue()); 
      } 

      if(!params.isEmpty()){ 
       request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); 
      } 
      new CallServiceTask().execute(request, url); 
      break; 
     } 
    } 
} 

private Object[] executeRequest(HttpUriRequest request, String url) 
{ 
    HttpClient client = new DefaultHttpClient(); 
    client = getNewHttpClient(); 

    HttpResponse httpResponse; 

    try { 
     httpResponse = client.execute(request); 
     HttpEntity entity = httpResponse.getEntity(); 

     if (entity != null) { 

      InputStream instream = entity.getContent(); 
      String response = convertStreamToString(instream); 
      try { 
       rtnData[0] = new JSONObject(response); 
       rtnData[1] = false; 

      } catch (JSONException e1) { 
       rtnData[1] = true; 
       e1.printStackTrace(); 
      } 

      // Closing the input stream will trigger connection release 
      instream.close(); 
     } 

    } catch (ClientProtocolException e) { 
     client.getConnectionManager().shutdown(); 
     e.printStackTrace(); 
    } catch (IOException e) { 
     client.getConnectionManager().shutdown(); 
     e.printStackTrace(); 
    } 
    return rtnData; 
} 


private static String convertStreamToString(InputStream is) { 

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

/** 
* Custom HTTP Client accepting all SSL Certified Web Services. 
* 
* @return n HttpClient object. 
*/ 
public HttpClient getNewHttpClient() { 
    try { 
     KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     trustStore.load(null, null); 

     SSLSocketFactory sf = new MySSLSocketFactory(trustStore); 
     sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

     HttpParams params = new BasicHttpParams(); 
     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 

     SchemeRegistry registry = new SchemeRegistry(); 
     registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
     registry.register(new Scheme("https", sf, 443)); 

     ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 

     return new DefaultHttpClient(ccm, params); 
    } catch (Exception e) { 
     return new DefaultHttpClient(); 
    } 
} 

Odpowiedz

24

Jedynym sposobem na to jest skorzystanie z funkcji Callback. Można zrobić coś takiego:

new CallServiceTask(this).execute(request, url); 

Następnie w CallServiceTask dodać zmienną klasy lokalnej i wywołać metodę z tej klasy w swojej onPostExecute:

private class CallServiceTask extends AsyncTask<Object, Void, Object[]> 
{ 
    RestClient caller; 

    CallServiceTask(RestClient caller) { 
     this.caller = caller; 
    } 


    protected Object[] doInBackground(Object... params) 
    { 
     HttpUriRequest req = (HttpUriRequest) params[0]; 
     String url = (String) params[1]; 
     return executeRequest(req, url); 
    } 

    protected onPostExecute(Object result) { 
     caller.onBackgroundTaskCompleted(result); 
    } 
} 

Następnie wystarczy użyć obiektu, jak chcesz w metoda onBackgroundTaskCompleted() w klasie RestClient.

Bardziej eleganckim i rozszerzalnym rozwiązaniem byłoby użycie interfejsów. Przykładowa implementacja znajduje się w bibliotece this. Właśnie zaczęłam, ale ma przykład tego, co chcesz.

8

Można użyć get() aby odzyskać value/object powrotem z AsyncTask.

new CallServiceTask().execute(parameters).get(); 

To spowoduje powrót computed rezultat, że wracają. Ale to zablokuje twój interfejs do czasu zakończenia procesu w tle.

Inną opcją jest utworzenie interfejsu lub programu BroadcastReceiver, który zwróci wartość, gdy tylko twoja doInBackground() zostanie ukończona. Stworzyłem demo tego samego interfejsu i BroadcastReceiver, dzięki któremu można sprawdzić, czy od my github

Ponadto, używając drugiego podejścia, Twój interfejs użytkownika nie zostanie zablokowany!

+3

Ale get() spowoduje również mój wniosek, aby zatrzymać się i poczekać aż metoda rzeczywiście wraca i od całego Celem używania AsyncTask było połączenie asynchroniczne z serwisem WWW. – CodePrimate

+1

Nie podążam. Mam swój LoginController, który jest używany przez moją Aktywność, gdy użytkownik naciśnie przycisk Zaloguj się. LoginController następnie tworzy instancję RestClient i wywołuje RestCLient.ExecuteCall. ExecuteCall dodaje parametry do adresu URL, a następnie wywołuje rtnData = new CallServiceTask(). Execute (parameters) .get(); W jaki sposób nie spowoduje to, że działanie pozostanie w pobliżu i będzie czekać na powrót funkcji get()? – CodePrimate

+0

Inną rzeczą, którą możesz zrobić, to użyć obliczonego wyniku w metodzie 'onPostExecute()' do wykonania dowolnej rzeczy interfejsu użytkownika. –

11

jako @ saad-farooq wspomniał, że możesz użyć do tego celu interface. Więc można użyć Handler.Callback lub zdefiniować własne:

public interface ClientIF { 

    public void onResponseReceived(Object result); 

} 

następnie trzeba zaimplementować go w CallServiceTask

public abstract class CallServiceTask extends AsyncTask<Object, Void, Object[]> 
    implements ClientIF 
{ 
    Activity activity; 

    CallServiceTask(Activity activity) { 
     this.activity = activity; 
    } 

    public abstract void onResponseReceived(Object result); 

    protected Object[] doInBackground(Object... params) 
    { 
     HttpUriRequest req = (HttpUriRequest) params[0]; 
     String url = (String) params[1]; 
     return executeRequest(req, url); 
    } 

    protected onPostExecute(Object result) { 
     onResponseReceived(result); 
    } 
} 

wiadomości, że costructor zostaje zmieniony tak, można zadzwonić z każdego Aktywny klasa. następnie dokonać wystąpienie tej klasy w swojej RestClient

public class RestClient 
{ 
CallServiceTask service = new CallServiceTask() { 
    @Override 
    public void onResponseReceived(Object result) { 
    // TODO Auto-generated method stub 

    } 
}; 

} 
1
public class getOperators extends AsyncTask<Void, Void, String> { 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     items = new ArrayList(); 
     dialog = new ProgressDialog(PrepaidOperatorsListActivity.this); 
     dialog.setMessage("Please Wait..."); 
     dialog.setCancelable(false); 
     dialog.show(); 
    } 



    @Override 
    protected String doInBackground(Void... params) { 
     BufferedReader reader; 
     StringBuffer buffer; 
     String res = null; 

     try { 
      URL url = new URL(""); 
      HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
      con.setReadTimeout(40000); 
      con.setConnectTimeout(40000); 
      con.setRequestMethod("GET"); 
      con.setRequestProperty("Content-Type", "application/json"); 
      int status = con.getResponseCode(); 
      InputStream inputStream; 
      if (status == HttpURLConnection.HTTP_OK) { 
       inputStream = con.getInputStream(); 
      } else { 
       inputStream = con.getErrorStream(); 
      } 
      reader = new BufferedReader(new InputStreamReader(inputStream)); 
      buffer = new StringBuffer(); 
      String line = ""; 
      while ((line = reader.readLine()) != null) { 
       buffer.append(line); 
      } 
      res = buffer.toString(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (ProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return res; 
    } 
    @Override 
    protected void onPostExecute(String s) { 
     super.onPostExecute(s); 
     System.out.println("JSON RESP:" + s); 
     String response = s; 
     try { 

      JSONObject ecomerrce = new JSONObject(response); 
      JSONArray jsonArray = ecomerrce.getJSONArray("prepaid_operators"); 

      for (int j = 0; j < jsonArray.length(); j++) { 
       JSONObject jsonObject = jsonArray.getJSONObject(j); 

       PrepaidOperatorsPojo prepaidOperatorsPojo = new PrepaidOperatorsPojo(jsonObject.getString("operator_name"), jsonObject.getString("operator_code"), jsonObject.getString("operator_display_comission"), jsonObject.getString("operator_calculate_comission")); 
       items.add(prepaidOperatorsPojo); 

      } 
      if (items.size() > 0) { 
       dialog.dismiss(); 
       prepaidOperatorListAdapter = new PrepaidOperatorListAdapter(PrepaidOperatorsListActivity.this, items); 
       rvPrepaidOperatorList.setAdapter(prepaidOperatorListAdapter); 

      } else { 
       dialog.dismiss(); 
       Toast.makeText(PrepaidOperatorsListActivity.this, "No Data to display", Toast.LENGTH_SHORT).show(); 
      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
1
private void walletStatements() { 
     JSONObject post_search = new JSONObject(); 
     try { 

      post_search.put("username", getUserName); 


     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     if (post_search.length() > 0) { 
      try { 
       new Getwalletstatements().execute(String.valueOf(post_search)); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    } 


    class Getwalletstatements extends AsyncTask<String, String, String> { 
     String JsonResponse = null; 
     ProgressDialog dialog; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

      dialog = new ProgressDialog(ReportsActivity.this); 
      dialog.setMessage("Please Wait..."); 
      dialog.setCancelable(false); 
      dialog.show(); 
     } 

     @Override 
     protected String doInBackground(String... params) { 
      String JsonDATA = params[0]; 
      HttpURLConnection urlConnection = null; 
      BufferedReader reader = null; 
      URL url = null; 

      try { 
       url = new URL(Constant.url+"GetReports_v9.php"); 
       urlConnection = (HttpURLConnection) url.openConnection(); 
       urlConnection.setDoOutput(true);    // is output buffer writter 
       urlConnection.setRequestMethod("POST"); 
       urlConnection.setRequestProperty("Content-Type", "application/json"); 
       urlConnection.setRequestProperty("Accept", "application/json");//set headers and method 
       Writer writer = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8")); 
       writer.write(JsonDATA);// json data 
       writer.close(); 

       InputStream inputStream = urlConnection.getInputStream();//input stream 
       StringBuffer buffer = new StringBuffer(); 
       if (inputStream == null) {     // Nothing to do. 
        return null; 
       } 
       reader = new BufferedReader(new InputStreamReader(inputStream)); 
       String inputLine; 

       while ((inputLine = reader.readLine()) != null) 
        buffer.append(inputLine + "\n"); 

       if (buffer.length() == 0) {     // Stream was empty. No point in parsing. 
        return null; 
       } 

       JsonResponse = buffer.toString(); 


       return JsonResponse; 

      } catch (MalformedURLException e) { 
       e.printStackTrace(); 
      } catch (ProtocolException e) { 
       e.printStackTrace(); 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
       if (urlConnection != null) { 
        urlConnection.disconnect(); 
       } 
       if (reader != null) { 
        try { 
         reader.close(); 
        } catch (final IOException e) { 

        } 
       } 
      } 


      return null; 
     } 

     @Override 
     protected void onPostExecute(String s) { 

      if (JsonResponse != null) { 
       try { 
        NetworkIN.iv= Constant.iv; 
        NetworkIN.change=Constant.key; 
        NetworkIN mCrypt=new NetworkIN(); 
        String decrypted = new String(mCrypt.decrypt(JsonResponse.trim())); 

        if(decrypted!=null){ 
         JSONObject ordersHistory = new JSONObject(decrypted); 
         msg = ordersHistory.getString("msg"); 

         JSONArray jsonArray = ordersHistory.getJSONArray("PPDetails"); 

         ordersCount = jsonArray.length(); 
         //for (int j = 0; j < jsonArray.length(); j++) 
         for (int j = jsonArray.length() - 1; j >= 0; j--) 
         { 
          JSONObject jsonObject = jsonArray.getJSONObject(j); 


          String message,total_in,inType ; 

          total_in =jsonObject.getString("total_in"); 
          inType =jsonObject.getString("in_type"); 
          message="Congratulations your wallet is credited by Rs."+total_in+" because of "+inType; 
          ReportsPojo reportsPojo = new ReportsPojo(jsonObject.getString("reg_id"), 
            jsonObject.getString("username"), 
            jsonObject.getString("transfer_from"), 
            jsonObject.getString("transfer_to"), 
            jsonObject.getString("total_in"), 
            jsonObject.getString("tds"), 
            jsonObject.getString("in_amount") , 
            jsonObject.getString("out_amount"), 
            jsonObject.getString("in_type"), 
            jsonObject.getString("created_on"), 
            message); 

          reportsItems.add(reportsPojo); 
         } 
        }else{ 

        } 


       } catch (JSONException e) { 
        e.printStackTrace(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

       if (msg.equals("Success")) { 

        reportsAdapter = new ReportsAdapter(ReportsActivity.this, reportsItems); 
        reportsListview.setAdapter(reportsAdapter); 

       } else { 
        Toast.makeText(ReportsActivity.this, "Sorry "+msg, Toast.LENGTH_LONG).show(); 

       } 
       dialog.dismiss(); 
      } else { 
       dialog.dismiss(); 
      } 
     } 
0
public class MyAsyncTask extends AsyncTask<String, Void, String> { 

    @Override  
    protected void onPreExecute() { 
     //showProgressDialog 
     dialog = new ProgressDialog(this); 
     dialog.setMessage("Loading........"); 
     dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
     dialog.show(); 
    } 

    @Override  
    protected String doInBackground(String... strings) { 
     HttpURLConnection httpURLConnection; 
     BufferedReader reader; 
     int responseCode ; 

     try { 
      URL url = new URL(YOUR_URL); 
      URLConnection urlConnection = url.openConnection(); 
      httpURLConnection = (HttpURLConnection) urlConnection; 
      httpURLConnection.setRequestMethod("GET"); 
      httpURLConnection.setDoOutput(true); 

      responseCode = httpURLConnection.getResponseCode(); 
      InputStream inputStream = httpURLConnection.getInputStream(); 
      if (inputStream != null) { 
       if (responseCode == 200) { 
        reader = new BufferedReader(new InputStreamReader(inputStream)); 
        StringBuilder buffer = new StringBuilder(); 
        String line; 
        while ((line = reader.readLine()) != null) { 
         buffer.append(line); 
        } 
        return buffer.toString(); 
       } 
      } 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override  
    protected void onPostExecute(String result) { 
     progressDialog.dismiss(); 
     // Fetch Your Data Add Your Code Here 
    } 
} 
Powiązane problemy