我的MainActivity上有一个AsynkTask方法,它包含以下内容:
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
声明的对象以及它的构造函数:
public Car(int idCar, String name)
{
this.idCar = idCar;
this.name = name;
}
我知道return cars;
会将名为ArrayList
的{{1}}返回给方法cars
,但我尝试从那里检索此onPostExecute
而我无法&# 39;因为它总是告诉我ArrayList
方法必须是onPostExecute
。
我还在我的Void
课程中声明了另一个ArrayList
:
MainActivity
所以我尝试将ArrayList<Car> totalCars = new ArrayList<Car>();
ArrayList克隆到我的cars
方法中的totalCars
ArrayList中,但它给出了一个错误,其中它表示:
&#39;克隆()&#39;在java.lang.Object&#39;中保护了访问权限。
这是试图克隆我的ArrayList的代码:
onPostExecute
所以我也尝试将我的值直接添加到protected void onPostExecute(ArrayList<Car> c)
{
for(Car cr: c)
{
totalCars.add(cr.clone());
}
}
方法上的totalCars
ArrayList:
doInBackground
但是当我执行totalCars.add(new Car(1,"Car1");
totalCars.add(new Car(2,"Car2");
totalCars.add(new Car(3,"Car3");
方法时:
AsyncTask
我的new chargeCars().execute();
ArrayList的大小等于0。
我该怎么办?我完全阻止,我搜索了一个答案,但我找不到任何对我有帮助的东西。
编辑:我的totalCars
课程:
Car
编辑2:我放了一些日志,看看我的程序究竟是什么,我得到了奇怪的结果:
正如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;
}
}
所说,我使用他的两种方法但其中任何一种都有效。我能看到什么?好吧,我在Clairvoyant
方法中看到,ArrayList包含两个方法中的值。这里没有问题。
当我在onPostExecute
类的onCreate
方法中执行AsyncTask时,问题是我的ArrayList MainActivity
里面没有任何值,但是在我的AsyncTask的方法totalCars
中,它包含了我放在ArrayList中的所有值。
可能是什么问题?
编辑3:我也尝试过:
onPostExecute
但仍然无法奏效。当我尝试在我的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
时,我还试图让Log
确保我的AsyncTask已经完成,但它也给了我一个错误(我还有另外一个问题,但是我不知道在SO中做一个好的做法是直接从另一个问题引用,所以我不在这里发布。
我做错了吗?为什么在我的onCreate
中,它为我提供了doInBackground
size
和ArrayList
方法中的正确值?
提前致谢!
答案 0 :(得分:7)
我做错了吗?为什么在我的doInBackground它给了我 正确的ArrayList大小和我的onCreate方法不是吗?
因为执行是异步的,UI Thread
不会导致AsyncTask
执行结束以继续执行流程。要获得结果,当AsyncTask
完成执行而不阻止UI Thread
时,您可以使用委托/列表。
让我们在Activity的顶部声明一个接口,让它实现这个接口(你需要实现这些方法)。调用onCarsCompleted
后,您就可以打印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
计算结果传回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);
}
}
}
:
new chargeCars(this).execute();
当然,您需要实例化
之类的AsyncTask{{1}}
答案 1 :(得分:2)
方法1: 不要使用clone只使用object来添加:
protected void onPostExecute(ArrayList<Car> c)
{
super.onPostExecute();
for(Car cr: c)
{
totalCars.add(cr);
}
//Code for further execution
}
方法2: 创建一个方法,在获得ArrayList
之后由onPostExceute()调用 protected void onPostExecute(ArrayList<Car> c)
{
super.onPostExecute();
setValues(c);
}
private void setValues(ArrayList<Car> c){
for(Car cr: c)
{
totalCars.add(cr);
}
//Code for further execution
}