我一直在做一堆研究并查看Android中ASyncTask的文档,但我似乎无法理解它。我只是想在一个片段在应用程序中可见时运行一些方法,但为了更容易做到这一点,我想我应该使用ASyncTask。我的示例代码如下:
private class syncExample extends ASyncTask <Void, Void, Void>
{
@Override
protected void onPreExecute()
{
}
@Override
protected void doInBackground(Void... voids)
{
}
@Override
protected void onProgressUpdate()
{
}
@Override
protected void onPostExecute()
{
}
}
现在我的问题如下:
在尖括号中,我有Void,Void,Void。这些代表到底是什么以及如何知道放置在哪里是正确的?
对于类中的每个方法,我将每个方法称为void。它们何时应该与void不同(如boolean,String,long等)?
对于doInBackground方法,我在括号中有Void ...空格。我究竟应该把它放在那里?它们代表什么?
感谢您的帮助。关于这个的文档对于像我这样的初学者来说并不是很清楚。
答案 0 :(得分:11)
AsyncTask使用参数化类型(java泛型),以便您可以指定在定义自己的AsyncTask时使用的类型。也许这种形式更容易解释:
public abstract class AsyncTask<Params, Progress, Result> {
...
protected abstract Result doInBackground(Params... params);
protected abstract void onProgressUpdate(Progress... progress);
protected abstract void onPostExecute(Result result);
...
}
没有名为Params,Progress或Result的类。这些是泛型类型。它们只是您在定义自己的AsyncTask子类时要使用的类型的占位符。上述内容同样可以写成:
public abstract class AsyncTask<A, B, C> {
...
protected abstract C doInBackground(A... params);
protected abstract void onProgressUpdate(B... progress);
protected abstract void onPostExecute(C result);
...
}
假设我正在定义一个AsyncTask,它接受一个表示URL的字符串列表,它将ping每个字符串以查看它是否可访问,然后返回可到达的数字。同时,每次测试时,每次测试完成后都会更新ProgressBar
。它可能看起来像这样:
public class MyAsyncTask extends AsyncTask<String, Integer, Integer> {
@Override
protected Integer doInBackground(String... params) {
int total = params.length;
int successfulPings = 0;
for (int i = 0; i < total; i++) {
if (isReachable(params[i])) {
successfulPings++;
}
publishProgress(i, total);
}
return successfulPings;
}
@Override
protected void onProgressUpdate(Integer... progress) {
int testsSoFar = progress[0];
int totalTests = progress[1];
progressBar.setMax(totalTests);
progressBar.setProgress(testSoFar);
}
@Override
protected void onPostExecute(Integer result) {
Toast.makeTest(context, "Reached " + result + " sites.", Toast.LENGTH_SHORT).show();
}
}
我会按如下方式启动:
String[] urls = ...
MyAsyncTask task = new MyAsyncTask();
task.execute(urls);
传递给execute
的参数将传递给doInBackground
。无论你在doInBackground
做什么,你都需要将作为参数传入的内容返回给onPostExecute
。在doInBackground
中,您可以致电publishProgress
,在那里您可以像我一样做(但您不必)。
答案 1 :(得分:0)
我的基本建议是更多地研究AsyncTask,但我也会尝试并回答你的问题:
1-在尖括号中,我有Void,Void,Void。这些代表到底是什么,我怎么知道放在哪里是正确的?
它们是重写方法的输入参数类型:doInBackground()onPreExecute(),onProgressUpdate()和.......
2-对于类中的每个方法,我将每个方法称为void。什么时候应该与void不同(比如boolean,String, 等等)?
我将给你一个例子:onPostExecute()保证在doInBackground()之后被调用,所以如果onPostExecute(int someCounter)在其输入中有一个整数,那么doInBackground()应该返回一个整数而不是void。所以它将被声明为:
int doInBackground(){
//bla bla bla
int someIntegerValue;
return someIntegerValue;
}
3-对于doInBackground()方法,我在括号中有Void ...空格。我究竟应该把它放在那里?他们是什么 代表什么?
它们是var-args,基本上,它们代表可变数量的参数。 详细了解他们here。
我再次建议您深入研究Android中的线程,并了解为什么需要AsyncTask。 祝你好运,
答案 2 :(得分:0)
异步任务使用的三种类型如下:
Params,执行时发送给任务的参数类型。即如果要将一些变量/数组发送到异步任务后台任务。您可以使用该变量来使用该信息。
进度,后台计算期间发布的进度单元的类型。即显示您的后台进度的进度。 (例如显示下载了多少视频/图像)
String [] username;
用户名[0] = “USER1”; 用户名[1] = “用户2”;
new asynctask()。execute(username);
private class asynctask extends AsyncTask <USER, Integer, String>
{
@Override
protected void onPreExecute()
{
// anything you want to do prior starting the async task.
}
@Override
protected String doInBackground(USER... users)
{
int count = users.length;
for (int i = 0; i < count; i++)
retriveinformation(users[i]);
return "Hey";
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(String result) {
// the value result is HEY that is returned by doInBackground.
}
}
并非所有类型都始终由异步任务使用。要将类型标记为未使用,只需使用类型Void。
取自https://developer.android.com/reference/android/os/AsyncTask.html
的信息答案 3 :(得分:0)
让我试试这个。我正在解析的所有信息都来自Karakuri在对问题的评论中分享的链接。
尖括号的内容按顺序称为“参数”,“进度”和“结果”。参数是将被输入“doInBackground”的参数类型(使用varargs)。它们将通过该方法在数组中接收。您将使用这些参数作为数据在后台线程中进行处理。
“进度”是输入onProgressUpdate的值的类型。覆盖此方法时,您将接收此类型的数据,对其进行格式化,并在进度显示中使用它。从我的阅读中,您可以在doInBackground中发布您的进度,以供onProgressUpdate使用。
“结果”是操作结果的数据类型。这将是doInBackground的返回类型,以及onPostExecute的参数类型。 对于包含“...”(称为varargs)的参数,您可以根据需要输入任意数量的参数。它们必须用逗号分隔,并且必须都是“......”之前指定的类型。这些项目将传递给数组中的函数。所以,回答你的问题:
一些想法:如果您是初学者,请暂时将“progress”保留为空,并且不要覆盖onProgressUpdate。它在生产代码中非常重要,但对于初学者学习项目来说却是一项额外的艰苦工作。 onPreExecute也可能比你的等级值得更麻烦。只记得它们存在,当你需要它们时,你可能会知道。此外,仅仅因为难以避免多线程主题的良好工作。