我有以下课程:
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);
但输出变量没有获取数据,而是出现错误:
Type mismatch: cannot convert from AsyncTask<String,Integer,String> to String
答案 0 :(得分:111)
方法execute
会返回AynscTask
本身,您需要致电get
:
output =
new getURLData()
.execute("http://www.example.com/call.php?locationSearched=" + locationSearched)
.get();
这将启动一个新线程(通过execute
),同时阻止当前线程(通过get
),直到新线程的工作完成并返回结果。
如果您这样做,只需将异步任务转换为同步。
但是,使用get
的问题是因为它阻塞,所以需要在工作线程上调用它。但是,需要在主线程上调用AsyncTask.execute()
。因此,尽管此代码可行,但您可能会得到一些不良结果。我还怀疑get()
未经Google严格测试,他们可能会在某个地方引入错误。
答案 1 :(得分:18)
我宁愿创建回调而不是阻止UI线程。 在您的类创建方法,将在数据到达时调用。例如:
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()将填充您的UI,因此没有理由使用AsyncTask。
答案 2 :(得分:4)
如果用户点击该按钮,则必须等待内容,他们同时做什么?
为什么不这样做:
这允许用户在处理请求时离开并执行任何操作。
IntentService在后台运行自己的线程。当它收到一个Intent时,它会在onHandleIntent()上运行。当该方法完成时,服务被缓存:它不是活动的,但是当下一个Intent到达时它可以快速重新启动。
答案 3 :(得分:2)
在构造函数中获取上下文:
public GetDataTask(Context context) {}
使用以下方法创建接口:
void onDataRetrieved(String data);
在您创建Task对象的类中实现Interface(例如MainActivity
)
将Context强制转换为接口并调用onDataRetrieved Method
答案 4 :(得分:1)
这个ONE LINER为我工作:
String result = MyasyncTask.execute(type, usrPhoneA, usrPWDA).get();
答案 5 :(得分:0)
在下面的代码中,我从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;
}
}
}
答案 6 :(得分:0)
向task的构造函数添加一个context参数,该构造函数将引用存储结果数据的对象。
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);
}
}
答案 7 :(得分:0)