Как получить данные из AsyncTasks doInBackground ()?

Я сохраню это как можно проще.

У меня есть метод на моем уровне управления, который использует класс CallServiceTask который расширяет AsyncTask . При вызове нового CallServiceTask().execute(parameters)
Как получить данные, возвращенные с doInBackground ? Во всех обучающих программах, которые я нашел, используется класс, который расширяет AsyncTask непосредственно из их Activity .
Моя проблема немного сложнее.
Все, что я хочу, – это вернуть Object[] возвращаемый doInBackground и установить его для частных членов данных моего класса RestClient .

CallServiceTask выглядит так:

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

И мой класс RestClient выглядит следующим образом:

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

Solutions Collecting From Web of "Как получить данные из AsyncTasks doInBackground ()?"

Единственный способ сделать это – использовать CallBack. Вы можете сделать что-то вроде этого:

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

Затем в вашей CallServiceTask добавьте локальную переменную класса и вызовите метод из этого класса в 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); } } 

Затем просто используйте Object, как вам нравится, в onBackgroundTaskCompleted() в вашем классе RestClient.

Более элегантным и расширяемым решением будет использование интерфейсов. Пример реализации см. В этой библиотеке. Я только начал, но у него есть пример того, что вы хотите.

Как упоминалось в @ saad-farooq, вы можете использовать интерфейс для этого. Таким образом, вы можете использовать Handler.Callback или определить свой собственный:

 public interface ClientIF { public void onResponseReceived(Object result); } 

То вам нужно реализовать его в своей 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); } } 

Обратите внимание на то, что структура затрат изменяется, поэтому вы можете звонить из каждого класса Activity . Затем сделайте экземпляр этого класса в RestClient

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

Вы можете использовать get() для извлечения вашего value/object из AsyncTask .

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

Это вернет вам computed результат, который вы возвращаете. Но это заблокирует ваш пользовательский интерфейс, пока ваш фоновый процесс не будет завершен.

Другой вариант – создать интерфейс или BroadcastReceiver, чтобы вы вернули вам значение, как только doInBackground() . Я создал демо для одного и того же использования интерфейса и BroadcastReceiver, которые вы можете проверить, если из моего github

Кроме того, используя второй подход, ваш пользовательский интерфейс не будет заблокирован!

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