常见问题和AsyncTask使用的一般说明
=> Where should I do network operations? Where should I return my aquired values?
通常,您应该在单独的线程中执行网络操作 – > doInBackground();因为您不希望在网络操作占用时间时冻结UI.因此,您应该连接到Service或.php脚本,或者从doInBackground()方法中获取数据的任何位置.然后你也可以在那里解析数据,并通过指定doInBackground()的返回类型来回复doInBackground()方法中的解析数据,更多关于那里的数据.然后,onPostExecute()方法将从doInBackground()接收返回的值,并使用UI表示它们.
=> AsyncTask< String, Integer, Long> ==> How does this work?
一般来说,AsyncTask类看起来像这样,它只不过是一个具有3个不同generic types的泛型类:
AsyncTask
You can specify the type of Parameter the AsyncTask takes, the Type of the Progress indicator and the type of the result (the return type
of doInBackGround()).
下面是一个AsyncTask的示例,如下所示:
AsyncTask
我们有参数的类型字符串,进度的类型整数和结果的类型长(返回类型为doInBackground()).您可以使用Params,Progress和Result所需的任何类型.
private class DownloadFilesTask extends AsyncTask {
// these Strings / or String are / is the parameters of the task, that can be handed over via the excecute(params) method of AsyncTask
protected Long doInBackground(String... params) {
String param1 = params[0];
String param2 = params[1];
// and so on...
// do something with the parameters...
// be careful, this can easily result in a ArrayIndexOutOfBounds exception
// if you try to access more parameters than you handed over
long someLong;
int someInt;
// do something here with params
// the params could for example contain an url and you could download stuff using this url here
// the Integer variable is used for progress
publishProgress(someInt);
// once the data is downloaded (for example JSON data)
// parse the data and return it to the onPostExecute() method
// in this example the return data is simply a long value
// this could also be a list of your custom-objects, ...
return someLong;
}
// this is called whenever you call puhlishProgress(Integer), for example when updating a progressbar when downloading stuff
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
// the onPostexecute method receives the return type of doInBackGround()
protected void onPostExecute(Long result) {
// do something with the result, for example display the received Data in a ListView
// in this case, "result" would contain the "someLong" variable returned by doInBackground();
}
}
=> How to use AsyncTask? How can I “call” it? How can I “execute” it?
在这种情况下,AsyncTask将String或String Array作为参数,一旦调用AsyncTask,它将如下所示:(指定的参数用于AsyncTask的execute(param)方法).
new DownloadFilesTask().execute("Somestring"); // some String as param
请注意,此调用没有返回值,您应该使用的唯一返回值是从doInBackground()返回的值.使用onPostExecute()方法确实可以使用返回的值.
这一行代码也要小心:(这个执行实际上会有一个返回值)
long myLong = new DownloadFilesTask().execute("somestring").get();
当AsyncTask正在执行时,.get()调用会导致UI线程被阻塞(因此,如果操作花费的时间超过几毫秒,UI会冻结),因为执行不会在单独的线程中执行.如果删除对.get()的调用,它将异步执行.
=> What does this notation “execute(String… params)” mean?
这是一个带有所谓“varargs”(变量参数)参数的方法.为了简单起见,我只想说这意味着你没有指定你可以通过这个参数传递给方法的实际值的数量,并且你给方法的任何数量的值都将被视为一个数组内的数组.方法.所以这个调用可能是这样的:
execute("param1");
但它也可能看起来像这样:
execute("param1", "param2");
甚至更多的参数.假设我们还在讨论AsyncTask,可以在doInBackground(String … params)方法中以这种方式访问参数:
protected Long doInBackground(String... params) {
String str1 = params[0];
String str2 = params[1]; // be careful here, you can easily get an ArrayOutOfBoundsException
// do other stuff
}