Возвращать данные из класса AsyncTask

Как получить данные из моей AsyncTask? My MainActivity вызывает функцию DataCall.getJSON, которая запускает AsyncTask, но я не уверен, как вернуть данные к исходной активности.

MainActivity с вызовом DataCall, который должен вернуть строку и сохранить ее в state_data

 String state_data = DataCall.getJSON(spinnerURL,spinnerContentType); 

DataCall:

 public class DataCall extends Activity { private static final String TAG = "MyApp"; private class DownloadWebPageTask extends AsyncTask<String, Void, String> { protected String doInBackground(String... urls) { String response = ""; for (String url : urls) { DefaultHttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); try { HttpResponse execute = client.execute(httpGet); InputStream content = execute.getEntity().getContent(); BufferedReader buffer = new BufferedReader( new InputStreamReader(content)); String s = ""; while ((s = buffer.readLine()) != null) { response += s; } } catch (Exception e) { e.printStackTrace(); } } return response; } protected void onPostExecute(String result) { //THIS IS WHERE I NEED TO RETURN MY DATA TO THE MAIN ACTIVITY. (I am guessing) } } public void getJSON(String myUrlString, String contentType) { DownloadWebPageTask task = new DownloadWebPageTask(); task.execute(new String[] { "http://www.mywebsite.com/" + myUrlString }); } } 

Ключом для меня было создание класса с именем URLWithParams или что-то, потому что AsyncTask разрешает отправлять только 1 тип IN, и мне нужен как URL, так и параметры для HTTP-запроса.

 public class URLWithParams { public String url; public List<NameValuePair> nameValuePairs; public URLWithParams() { nameValuePairs = new ArrayList<NameValuePair>(); } } 

А затем отправлю его в JSONClient:

 public class JSONClient extends AsyncTask<URLWithParams, Void, String> { private final static String TAG = "JSONClient"; ProgressDialog progressDialog ; GetJSONListener getJSONListener; public JSONClient(GetJSONListener listener){ this.getJSONListener = listener; } @Override protected String doInBackground(URLWithParams... urls) { return connect(urls[0].url, urls[0].nameValuePairs); } public static String connect(String url, List<NameValuePair> pairs) { HttpClient httpclient = new DefaultHttpClient(); if(url == null) { Log.d(TAG, "want to connect, but url is null"); } else { Log.d(TAG, "starting connect with url " + url); } if(pairs == null) { Log.d(TAG, "want to connect, though pairs is null"); } else { Log.d(TAG, "starting connect with this many pairs: " + pairs.size()); for(NameValuePair dog : pairs) { Log.d(TAG, "example: " + dog.toString()); } } // Execute the request HttpResponse response; try { // Prepare a request object HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new UrlEncodedFormEntity(pairs)); response = httpclient.execute(httpPost); // Examine the response status Log.i(TAG,response.getStatusLine().toString()); BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8")); String json = reader.readLine(); return json; } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override protected void onPostExecute(String json ) { getJSONListener.onRemoteCallComplete(json); } public interface GetJSONListener { public void onRemoteCallComplete(String jsonFromNet); } } 

Затем назовите это из моего основного класса следующим образом:

 public class BookCatalog implements GetJSONListener { private final String TAG = this.getClass().getSimpleName(); private String catalog_url = "URL"; private void getCatalogFromServer() { URLWithParams mURLWithParams = new URLWithParams(); mURLWithParams.url = catalog_url; try { JSONClient asyncPoster = new JSONClient(this); asyncPoster.execute(mURLWithParams); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void onRemoteCallComplete(String jsonBookCatalogList) { Log.d(TAG, "received json catalog:"); Log.d(TAG, jsonBookCatalogList); JSONObject bookCatalogResult; try { bookCatalogResult = (JSONObject) new JSONTokener(jsonBookCatalogList).nextValue(); JSONArray books = bookCatalogResult.getJSONArray("books"); if(books != null) { ArrayList<String> newBookOrdering = new ArrayList<String>(); int num_books = books.length(); BookCatalogEntry temp; DebugLog.d(TAG, "apparently we found " + Integer.toString(num_books) + " books."); for(int book_id = 0; book_id < num_books; book_id++) { JSONObject book = books.getJSONObject(book_id); String title = book.getString("title"); int version = book.getInt("price"); } } } catch (JSONException e) { e.printStackTrace(); } } } 

AsyncTask свою AsyncTask как AsyncTask ниже:

 public class GetData extends AsyncTask<String, Void, String> { DataDownloadListener dataDownloadListener; public GetData() { //Constructor may be parametric } public void setDataDownloadListener(DataDownloadListener dataDownloadListener) { this.dataDownloadListener = dataDownloadListener; } @Override protected Object doInBackground(Object... param) { // do your task... return null; } @Override protected void onPostExecute(Object results) { if(results != null) { dataDownloadListener.dataDownloadedSuccessfully(results); } else dataDownloadListener.dataDownloadFailed(); } public static interface DataDownloadListener { void dataDownloadedSuccessfully(Object data); void dataDownloadFailed(); } } 

И использовать его в своей деятельности

 GetData getdata = new GetData(); getdata.setDataDownloadListener(new DataDownloadListener() { @SuppressWarnings("unchecked") @Override public void dataDownloadedSuccessfully(Object data) { // handler result } @Override public void dataDownloadFailed() { // handler failure (eg network not available etc.) } }); getdata.execute(""); 

ПРИМЕЧАНИЕ . Для людей, которые читают это.

Пожалуйста, рассмотрите этот пост для лучшей и, возможно, правильной реализации.

Хотя я не согласен с созданием нового действия для этой простой задачи,

 startActivityForResult() 

Для получения данных из другого вида деятельности.

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

Сериализуйте его, а затем прочитайте. Единственный способ, о котором я знаю.

Некоторые варианты:

A) Сделайте свой bean-интерфейс Serializable интерфейсом, вы можете передать свой bean-компонент через Intent.

B) Внедрить интерфейс Application (вам нужно сделать запись в манифесте). У вас есть метод setter \ getter в вашем классе Application. Вы можете установить свой компонент в приложении из AsyncTask и позже получить из Activity.

Извините за ответ так поздно, я думаю, к этому времени вы, возможно, решили эту проблему. Когда я искал что-то еще, я наткнулся на ваш вопрос. Я вставляю ссылку здесь, которая может помочь другим.