如何从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,则必须等待内容,他们同时做了什么?
为什么不这样做:
- 用户点击button。
- 你检查连接 。 如果用户没有连接到互联网,告诉他们。
- 通过发送Intent来发送HTTP请求来启动一个IntentService。
- 请求完成后,您发布通知。
- 用户点击通知,返回到可以执行下一步的活动。
这允许用户在请求正在处理的时候closures并执行任何操作。
IntentService在其自己的线程后台运行。 当它收到一个意图,它运行onHandleIntent()。 当该方法结束时,服务被caching:它不是活动的,但当下一个Intent到达时它可以快速重新启动。
-
在构造函数中获取上下文,如下所示:
public GetDataTask(Context context) {}
-
用方法创build一个接口:
void onDataRetrieved(String data);
-
在创buildTask对象的类中实现接口(例如
MainActivity
) -
将上下文转换到接口并调用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你想要的任何活动