即使在Developer.Android上阅读了有关它的所有内容之后,我也很难理解AsyncTask。我正在寻找一些有关如何进行的见解。情况就是这样:
我有一个Activity,在onClick事件上调用底层LoginController类的LoginCheck()方法。然后LoginController类继续从UserInfo类或Activity(用户和密码)获取任何信息,并创建一个RestClient实例,然后调用Web服务并尝试登录.RestClient有一个私有扩展AsyncTask的类CallServiceTask。
我在这里遇到一些设计问题,希望你能提供帮助。
您将在下面找到相关项目的片段:
RESTClient实现
// From the constructor...
rtnData = new Object[]{ new JSONObject() , Boolean.TRUE };
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(request, url);
jsonData = ((JSONObject) rtnData[0]).optJSONObject("data");
connError = (Boolean) rtnData[1];
break;
}
case POST: ....
}
}
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;
}
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);
}
@Override
protected void onPostExecute(Object[] result)
{
rtnData = result;
}
}
答案 0 :(得分:2)
任何可能长时间运行的操作都应该在不同的线程中执行,这是绝对正确的。 AsyncTask
是解决此类问题的好方法,因为它还为您提供了一种将任务与UI线程同步的简便方法。这是你第一个问题的答案。
现在,关于UI线程更新,以向您的用户显示您的应用程序未被卡住。由于AsyncTask
的{{1}}和onPreExecute()
方法在UI线程中运行,因此您可以轻松地创建,运行和停止onPostExecute()
或ProgressDialog
。如果您想显示任务的当前进度,您应该在ProgressBar
内调用publishProgress(int)
方法,然后在doInBackground()
的{{1}}方法中使用它。例如,您可以更新AsyncTask
。
要从AsyncTask中获取结果,您可以调用其onProgressUpdate()
方法(这是一个同步调用),或者实现某种回调接口,该接口将告诉活动该任务已完成。
我希望答案很清楚,如果没有 - 随意提出更多问题。希望这会有所帮助。
编辑
使用一种方法[{1}}创建一个名为ProgressDialog
的接口。启动get()
的活动必须实现此接口。现在在onFetchFinishedListener
中创建一个构造函数,该构造函数将void onFetchFinished(String)
对象作为参数,并在实例化活动中的AsyncTask
时发送对AsyncTask
的引用作为参数(因为它实现了OnFetchFinishedListener
)。然后,当您在AsyncTask
内部完成任务时,请在活动中调用Activity
。现在,在OnFetchFinishedListener
的{{1}}方法中,您可以使用回调带来的doInBackground()
(或其他对象)。再一次,希望我足够清楚。