如何从AsyncTask返回一个string?

我有以下class级:

public class getURLData extends AsyncTask<String, Integer, String>{ @Override protected String doInBackground(String... params) { String line; try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(params[0]); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); line = EntityUtils.toString(httpEntity); } catch (UnsupportedEncodingException e) { line = "<results status=\"error\"><msg>Can't connect to server</msg></results>"; } catch (MalformedURLException e) { line = "<results status=\"error\"><msg>Can't connect to server</msg></results>"; } catch (IOException e) { line = "<results status=\"error\"><msg>Can't connect to server</msg></results>"; } return line; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); } } 

我想这样称呼它:

 String output = null; output = new getURLData().execute("http://www.domain.com/call.php?locationSearched=" + locationSearched); 

但输出variables没有获取数据,而是我得到一个错误:

 Type mismatch: cannot convert from AsyncTask<String,Integer,String> to String 

该方法execute返回AynscTask本身,你需要调用get

 output = new getURLData() .execute("http://www.domain.com/call.php?locationSearched=" + locationSearched) .get(); 

然而,如果你这样做,你只是把你的asynchronous任务变成了同步任务,因为如果需要的话, get等待结果变得可用。

参考: AsyncTask.get

我宁愿创buildcallback比阻止UI线程。 在你的类中创build数据到达时将被调用的方法。 例如:

 private void setData(String data){ mTextView.setText(data); } 

然后在AsyncTask中实现onPostExecute:

 @Override protected void onPostExecute(String result) { setData(result); } 

然后在代码中的某个地方执行任务:

 new getURLData().execute(... 

当任务完成setData被调用和mTextView被填充。

AsyncTask.get()会让你的用户界面变得臃肿,所以没有理由使用AsyncTask。

如果用户点击该button,则必须等待内容,他们同时做了什么?

为什么不这样做:

  1. 用户点击button。
  2. 检查连接 。 如果用户没有连接到互联网,告诉他们。
  3. 通过发送Intent来发送HTTP请求来启动一个IntentService。
  4. 请求完成后,您发布通知。
  5. 用户点击通知,返回到可以执行下一步的活动。

这允许用户在请求正在处理的时候closures并执行任何操作。

IntentService在其自己的线程后台运行。 当它收到一个意图,它运行onHandleIntent()。 当该方法结束时,服务被caching:它不是活动的,但当下一个Intent到达时它可以快速重新启动。

  1. 在构造函数中获取上下文,如下所示:

    public GetDataTask(Context context) {}

  2. 用方法创build一个接口:

    void onDataRetrieved(String data);

  3. 在创buildTask对象的类中实现接口(例如MainActivity

  4. 将上下文转换到接口并调用onDataRetrieved方法

在下面的代码中,我从AsyncTask中获得一个String(directorName)。

 public class GetDirector { String id; private String baseURL = "http://www.omdbapi.com/?i="; private String finalURL = ""; String theDirector; public GetDirector(String imdbID) throws ExecutionException, InterruptedException { id= imdbID; finalURL = baseURL + id + "&plot=full&r=json"; System.out.println("GetDirector. finalURL= " + finalURL); theDirector = new GetDirectorInfo().execute().get(); } public String getDirector (){ return theDirector; } private class GetDirectorInfo extends AsyncTask<Void, Void,String> { @Override protected String doInBackground(Void... params) { String directorName = null; ServiceHandler sh = new ServiceHandler(); // Making a request to url and getting response String jsonStr = sh.makeServiceCall(finalURL, ServiceHandler.GET); System.out.println("Act_DetailsPage. jsonStr= " + jsonStr); if (jsonStr != null) { try { JSONObject everything = new JSONObject(jsonStr); directorName = everything.getString(JSON_Tags.TAG_DIRECTOR); System.out.println("directorName= "+ directorName); } catch (JSONException e) { e.printStackTrace(); } } else { System.out.println("Inside GetDirector. Couldn't get any data from the url"); } return directorName; } } } 

将上下文参数添加到任务的构造函数中,该构造函数将引用将存储结果数据的对象。

 class PopulateArray extends AsyncTask<Integer, Integer, ArrayList<String>> { Context _context; // context may be what ever activity or object you want to store result in PopulateArray(Context context) { _context = context; } @Override protected ArrayList<String> doInBackground(Integer... integers) { ArrayList<String> data = new ArrayList<String>(); //manipulate return data; } @Override protected void onPostExecute(ArrayList<String> strings) { _context.setData(strings); } } 

这ONE LINER为我工作:

 String result = MyasyncTask.execute(type, usrPhoneA, usrPWDA).get(); 

这对我有效。

Class1:

 new CallAPI(this).execute("Passing String",data); 

Class1:

 private void setData(String data){ mTextView.setText(data); } 

然后在AsyncTask中实现onPostExecute:

  @Override protected void onPostExecute(String result) { MainActivity main=new MainActivity(); main.setData(result); } 

这将返回你想setData你想要的任何活动