2012-02-14 28 views
16

Tôi sẽ giữ cái này đơn giản nhất có thể.Làm cách nào để truy xuất dữ liệu từ AsyncTasks doInBackground()?

Tôi có một phương pháp trong lớp điều khiển của mình sử dụng lớp CallServiceTask kéo dài AsyncTask. Khi gọi số CallServiceTask().execute(parameters)
mới Làm cách nào để truy xuất dữ liệu được trả lại từ doInBackground? Tất cả các hướng dẫn tôi đã tìm thấy sử dụng lớp mở rộng AsyncTask trực tiếp từ Activity của chúng.
Vấn đề của tôi phức tạp hơn một chút.
Tất cả những gì tôi muốn là lấy Object[] được trả về bởi doInBackground và đặt nó cho các thành viên dữ liệu riêng tư của lớp RestClient của tôi.

CallServiceTask trông như thế này:

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

Và lớp RestClient của tôi trông như thế này:

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

Trả lời

24

Cách duy nhất để thực hiện việc này là sử dụng Gọi lại. Bạn có thể làm một cái gì đó như thế này:

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

Sau đó, trong CallServiceTask bạn thêm một biến lớp học của địa phương và gọi một phương thức từ lớp đó trong onPostExecute của bạn:

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

Sau đó, chỉ cần sử dụng các đối tượng như bạn muốn trong phương thức onBackgroundTaskCompleted() trong lớp RestClient của bạn.

Giải pháp thanh lịch và mở rộng hơn là sử dụng giao diện. Để triển khai ví dụ, hãy xem thư viện this. Tôi đã bắt đầu nó nhưng nó có một ví dụ về những gì bạn muốn.

8

Bạn có thể sử dụng get() để lấy bạn value/object trở lại từ AsyncTask.

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

Điều này sẽ trả lại cho bạn computed dẫn đến việc bạn quay trở lại. Nhưng điều này sẽ chặn giao diện người dùng của bạn cho đến khi quá trình nền của bạn hoàn tất.

Một tùy chọn khác là tạo Giao diện hoặc BroadcastReceiver mà bạn trả lại cho bạn giá trị ngay khi bạn hoàn tất doInBackground(). Tôi đã tạo bản trình diễn cho cùng một giao diện bằng cách sử dụng Giao diện và BroadcastReceiver, bạn có thể kiểm tra xem có từ my github

Ngoài ra, bằng cách sử dụng giao diện người dùng thứ hai, UI của bạn sẽ không bị chặn!

+3

Nhưng get() cũng sẽ gây ra ứng dụng của tôi phải dừng lại và chờ đợi cho đến khi phương pháp này thực sự trở lại và kể từ khi toàn bộ điểm của việc sử dụng AsyncTask là để thực hiện cuộc gọi đến dịch vụ web không đồng bộ. – CodePrimate

+1

Tôi không theo. Tôi có LoginController của mình, được sử dụng bởi Hoạt động của tôi khi người dùng nhấn nút Đăng nhập. LoginController sau đó instantiates các RestClient và gọi RestCLient.ExecuteCall. ExecuteCall thêm các tham số vào url và sau đó gọi rtnData = new CallServiceTask(). Execute (tham số) .get(); Làm thế nào điều này sẽ không làm cho Hoạt động ngồi xung quanh và chờ get() trả lại? – CodePrimate

+0

Điều khác bạn có thể làm là sử dụng kết quả tính toán trong phương thức 'onPostExecute()' để thực hiện bất kỳ công cụ giao diện người dùng nào. –

11

như @ saad-farooq đã đề cập bạn có thể sử dụng interface cho điều đó. Vì vậy, bạn có thể sử dụng Handler.Callback hoặc xác định của riêng bạn:

public interface ClientIF { 

    public void onResponseReceived(Object result); 

} 

thì bạn cần phải thực hiện nó trong CallServiceTask bạn

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

lưu ý rằng costructor được thay đổi, do đó bạn có thể gọi từ mỗi Hoạt động lớp học. Sau đó thực hiện thể hiện của lớp này trong RestClient bạn

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 
    } 
} 
Các vấn đề liên quan