如何从AsyncTask返回ArrayList? [英] How can I return an ArrayList from my AsyncTask?
问题描述
我的MainActivity上有一个AsynkTask方法,如下所示:
I have an AsynkTask method on my MainActivity that it's the following:
class chargeCars extends AsyncTask<Void, Integer, ArrayList<Car>> {
protected void onPreExecute(){
}
protected ArrayList<Car> doInBackground(Void... params) {
ArrayList<Car> cars = new ArrayList<Car>();
cars.add(new Car(1,"Car1");
cars.add(new Car(2,"Car2");
cars.add(new Car(3,"Car3");
return cars;
}
protected void onProgressUpdate(){
}
protected void onPostExecute(ArrayList<Car> c){
}
}
其中Car
是我在另一个Class
中声明的对象,它是哪个构造函数:
where Car
it's an object that I have declared in another Class
and which constructor it's:
public Car(int idCar, String name)
{
this.idCar = idCar;
this.name = name;
}
,而且我知道return cars;
将名为cars
的ArrayList
返回到方法onPostExecute
,但是我尝试从那里检索此ArrayList
,但我不能,因为它总是对我说Void
.
and I know that return cars;
returns the ArrayList
named cars
to the method onPostExecute
but I tried to retrieve this ArrayList
from there and I couldn't because it always said to me that onPostExecute
method have to be Void
.
在我的MainActivity
类中还声明了另一个ArrayList
:
I have also another ArrayList
declared in my MainActivity
class:
ArrayList<Car> totalCars = new ArrayList<Car>();
所以我尝试的是在onPostExecute
方法中将cars
ArrayList克隆到我的totalCars
ArrayList中,但是它给了我一个错误,它说:
so what I tried it's to clone cars
ArrayList into my totalCars
ArrayList in my onPostExecute
method but it gives me an error in which it says that:
'clone()'已保护对'java.lang.Object'的访问
'clone()' has protected access in 'java.lang.Object'
这是试图克隆我的ArrayList的代码:
Here it's the code trying to clone my ArrayList:
protected void onPostExecute(ArrayList<Car> c)
{
for(Car cr: c)
{
totalCars.add(cr.clone());
}
}
因此,我还尝试将我的值直接添加到我的doInBackground
方法上的totalCars
ArrayList中:
So I also tried to add my values directly to my totalCars
ArrayList on my doInBackground
method:
totalCars.add(new Car(1,"Car1");
totalCars.add(new Car(2,"Car2");
totalCars.add(new Car(3,"Car3");
但是当我执行我的AsyncTask
方法时:
but when I execute my AsyncTask
method:
new chargeCars().execute();
我的totalCars
ArrayList的大小等于0.
the size of my totalCars
ArrayList it's equals to 0.
我该怎么办?我完全被封锁了,我在SO中搜寻答案,但找不到任何对我有帮助的东西.
What should I do? I'm totally block and I searched in SO for an answer but I couldn't find anything that helps to me.
我的Car
类别是:
public class Car {
private int idCar;
private String name;
public Car(){};
public Car(int idCar, String name)
{
this.idCar = idCar;
this.name = name;
}
public void setIdCar(int idCar)
{
this.idCar = idCar;
}
public int getIdCar()
{
return idCar;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
我放了一些日志以查看我的程序到底做了什么,并且得到了奇怪的结果:
EDIT 2: I put some logs to see what exactly does my program and I got strange results:
正如Clairvoyant
所说,我使用了他的两种方法,但是它们中的任何一种都有效.我能看到什么?好吧,我看到在onPostExecute
方法中,ArrayList在两个方法中都包含值.这里没有问题.
As Clairvoyant
said, I use both of his methods but any of them works. What could I saw? Well, I saw that in the onPostExecute
method the ArrayList contains values in both of the methods. Here there is no problem.
问题在于,当我在MainActivity
类的方法onCreate
中执行AsyncTask时,我的ArrayList totalCars
里面没有任何值,但是在我的AsyncTask的方法onPostExecute
中却有我放入ArrayList中的所有值.
The problem it's that when I execute the AsyncTask in the method onCreate
of my MainActivity
class, my ArrayList totalCars
doesn't have any value inside, but in the method onPostExecute
of my AsyncTask it has all the values that I put inside the ArrayList.
可能是什么问题?
我也尝试过:
public class MainActivity extends ActionBarActivity {
ArrayList<Car> cars = new ArrayList<Car>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new chargeCars().execute();
Log.d("Size onCreate: ", "" + cars.size()); //It returns me a 0 -->Incorrect
}
class chargeCars extends AsyncTask<Void, Integer, Boolean> {
protected void onPreExecute(){
}
protected ArrayList<Car> doInBackground(Void... params) {
cars.add(new Car(1,"Car1");
cars.add(new Car(2,"Car2");
cars.add(new Car(3,"Car3");
Log.d("Size: ", "" + cars.size()); //It gives me the size equals to 3 -->Correct
return true;
}
protected void onProgressUpdate(){
}
protected void onPostExecute(boolean c){
}
}
}
但是仍然不起作用.我还尝试制作一个ProgressDialog
来确保我的AsyncTask在我尝试在onCreate
方法中使用我的Log
时完成,但是它也给我一个错误(我对此有另一个疑问,但是我不知道直接从另一个问题进行引用是否是SO的良好做法,所以我不在此发布.)
But still doesn't work. I also tried to make a ProgressDialog
to be secure that my AsyncTask it's finished when I try to use my Log
in my onCreate
method but it also gives me an error (I have another question in SO about it but I don't know if it's a good practice in SO to make directly reference from another question so I don't post it here).
我做错什么了吗?为什么在我的doInBackground
中它为我提供了ArrayList
的正确size
而在我的onCreate
方法中却没有?
Am I doing something wrong? Why in my doInBackground
it gives me the correct size
of the ArrayList
and in my onCreate
method not?
提前谢谢!
推荐答案
我做错什么了吗?为什么在我的doInBackground中,它给了我 正确的ArrayList的大小,在我的onCreate方法中不是吗?
Am I doing something wrong? Why in my doInBackground it gives me the correct size of the ArrayList and in my onCreate method not?
因为执行是异步的,并且UI Thread
不能结束AsyncTask
的执行以继续其执行流程.要获得结果,请在AsyncTask
完成执行时不阻塞UI Thread
的情况下,可以使用委托/列表.
Because the execution is asynchronous and the UI Thread
doesn't way the end of the execution of your AsyncTask
to continue its execution flow. To get the results back, when your AsyncTask
finishes its execution, without blocking the UI Thread
, you could use a delegate/lister.
让我们在Activity的顶部声明一个接口,让我们不要实现该接口(您将需要实现这些方法).调用onCarsCompleted
时,您将能够打印正确尺寸的ArrayList
Let's declare an interface on the top of your Activity, and let't it implement this interface (you'll need to implement the methods). When onCarsCompleted
is invoked you'll be able to print the correct size of your ArrayList
public class MainActivity extends ActionBarActivity implements OnCarsListener {
public interface OnCarsListener {
void onCarsCompleted(ArrayList<Car> cars);
void onCarsError(String error);
}
// the other code
public void onCarsCompleted(ArrayList<Car> cars) {
Log.d("Size: ", "" + cars.size());
}
public void onCarsError(String error) {
}
}
现在我们在您的AsyncTask
中添加一个构造函数,该构造函数将OnCarsListener
类型的对象作为参数,并在chargeCars
范围内保留对该对象的成员引用,并且onPostExecute
我们进行通讯到Activity
计算结果:
now we add a constructor to your AsyncTask
, which takes as parameter an object of type OnCarsListener
, and we keep a member reference to the object in the scope of chargeCars
, and onPostExecute
we communicate back to the Activity
the results of your computation:
class chargeCars extends AsyncTask<Void, Integer, ArrayList<Car>> {
private final OnCarsListener mListener;
ArrayList<Car> cars = new ArrayList<Car>();
public chargeCars(OnCarsListener listener) {
mListener = listener;
}
protected void onPreExecute(){
}
protected ArrayList<Car> doInBackground(Void... params) {
cars.add(new Car(1,"Car1");
cars.add(new Car(2,"Car2");
cars.add(new Car(3,"Car3");
Log.d("Size: ", "" + cars.size()); //It gives me the size equals to 3 -->Correct
return cars;
}
protected void onProgressUpdate(){
}
protected void onPostExecute(ArrayList<Car> cars){
if (mListener != null) {
mListener.onCarsCompleted(cars);
}
}
}
当然,您需要像这样实例化AsyncTask
And of course, you need to instantiate the AsyncTask like
new chargeCars(this).execute();
这篇关于如何从AsyncTask返回ArrayList?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!