我最近开始学习android,但是Asynctask概念让我很烦。
我的问题是doInBackground(Param ...params)
和execute(Params... params)
如何相互关联。 execute()
方法如何将其争论传递给doInBackground()
方法。
我真的很感激一些帮助!
答案 0 :(得分:0)
我认为您对与varargs
相关联的generics
和AsyncTask
感到困惑。为了解释它,我将举一个简单的例子:
class AddStringTask extends AsyncTask<Void, String, Void> {
@Override
protected Void doInBackground(Void... unused) {
for (String item : items) {
if (isCancelled())
break;
publishProgress(item);
SystemClock.sleep(400);
}
return(null);
}
@Override
protected void onProgressUpdate(String... item) {
if (!isCancelled()) {
adapter.add(item[0]);
}
}
@Override
protected void onPostExecute(Void unused) {
Toast.makeText(getActivity(), R.string.done, Toast.LENGTH_SHORT)
.show();
task=null;
}
}
4
通常会AsyncTask
种方法:
onPreExecute()
[可选] - 在启动后台线程之前在UI线程上运行任务,例如:显示进度条。doInBackground()
[必须] - 从后台线程执行代码的方法。onProgressUpdate()
[可选]在后台线程执行操作时传递数据,例如:在执行下载操作时将下载百分比传递给用户。这是在主线程上执行的。onPostExecute()
[可选]此方法在doInBackground()
方法完成执行后立即执行。例如:您可以在下载完成时关闭进度条。现在进入仿制药:<Void, String, Void>
[在这种情况下]
doInBackground()
收到三种数据类型中的第一种,即Void
。您可以更改数据类型。如果您有要下载的URL的列表,则可以将其更改为String数组的变量。在这种情况下,由于我们没有任何信息要传递给doInBackground()
方法,因此我们将其设置为Void
。 onProgressUpdate()
方法将收到第二种数据类型的变量。即<Void, String, Void>
- &gt; String
。这将是从doInBackground()
方法传递的数据的形式。 doInBackground()
将第3种数据类型返回到onPostExecute()
,在本例中为Void
,如果您需要传递其他数据类型,您也可以自由执行。所以:<Void, String, Void>
- &gt;在这种情况下Void
。 execute()
方法只是启动AsyncTask()
来完成工作:
AddStringTask task=new AddStringTask();
task.execute();
答案 1 :(得分:0)
基本上每当类或子类扩展AsyncTask&lt; Params1 , Progress2 , Result3 &GT; 3种通用类型:
和4个步骤:
示例1:
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return result;
}
@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
@Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Processing...");
progressDialog.show();
}
}
}
启动后台任务1:
new LongOperation().execute();
示例2:
private class GetXMLTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
String output = null;
for (String url : urls) {
output = getOutputFromUrl(url);
}
return output;
}
private String getOutputFromUrl(String url) {
StringBuffer output = new StringBuffer("");
try {
InputStream stream = getHttpConnection(url);
BufferedReader buffer = new BufferedReader(
new InputStreamReader(stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
} catch (IOException e1) {
e1.printStackTrace();
}
return output.toString();
}
// Makes HttpURLConnection and returns InputStream
private InputStream getHttpConnection(String urlString)
throws IOException {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return stream;
}
@Override
protected void onPostExecute(String output) {
outputText.setText(output);
}
}
}
启动后台任务2:
// URL = "http://alkathirikhalid.com/message.html"
GetXMLTask task = new GetXMLTask();
task.execute(new String[] { URL });
示例3:
public class PostAsyncTask extends AsyncTask<Pair<Context, String>, Void, String> {
private Context context;
@Override
protected String doInBackground(Pair<Context, String>... params) {
context = params[0].first;
String name = params[0].second;
HttpClient httpClient = new DefaultHttpClient();
// http://10.0.2.2:8080/hello
HttpPost httpPost = new HttpPost("http://mail-portal.appspot.com/hello"); // 10.0.2.2 is localhost's IP address in Android emulator
try {
// Add name data to request
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("name", name));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() == 200) {
return EntityUtils.toString(response.getEntity());
}
return "Error: " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase();
} catch (ClientProtocolException e) {
return e.getMessage();
} catch (IOException e) {
return e.getMessage();
}
}
@Override
protected void onPostExecute(String result) {
Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
}
启动后台任务3:
new PostAsyncTask().execute(new Pair<Context, String>(this, "Some String"));
进一步资源:
答案 2 :(得分:0)
这是来自AsyncTask.java here
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
它需要变量参数,因此当你调用execute方法时,它实际上调用了这个方法。
从这里它所做的全部是`exec.execute(mFuture)
mFuture
已在AsyncTask构造函数中设置如下图所示。
因此在mWorker call()
方法内部,您实际上可以看到正在调用的doInBackground()。希望它能回答你的疑问:)