更改线程内的父类变量

时间:2017-03-24 17:36:25

标签: java android multithreading

我在Android中有类似的课程:

public class MyActivity extends Activity
{
    private ArrayList<Vehicle> vehicles;
    private final Context CONTEXT = this;
    ...

    public void method()
    {
        vehicles = new ArrayList<>();

        Thread t = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                vehicles.add(new Vehicle());
                AlertDialog.Builder b = new AlertDialog.Builder(CONTEXT);
                b.setMessage(vehicles.size());
                b.create().show();
                // b displays the correct size here
            }
        });
        t.start();
        AlertDialog.Builder b = new AlertDialog.Builder(CONTEXT);
        b.setMessage(vehicles.size());
        b.create().show();
        // b displays 0 here
    }
}

我的问题是vehicles内容仅在我的帖子内部发生变化(我注意到通过放置AlertDialog并显示其大小),但是当我的线程死亡时,更改不会保留, vehicles的大小为0。 我试图将vehicles.add(new Vehicle())语句放在runOnUiThread方法中,但大小仍然保持为0。

2 个答案:

答案 0 :(得分:0)

不是保留变量的问题,而是Java线程执行顺序!使用多线程代码执行不再是顺序执行。在您的示例中,无法知道AlertDialog method函数之前是否会调用来自Thread的{​​{1}}(看起来不是这样)。

欢迎使用多线程魔术。

run

答案 1 :(得分:0)

我喜欢这样的东西是创建一个父类可以实现的监听器接口。它允许您将执行完全切换回父原始线程类以及任何对象。

你的主要问题是时间,在线程开始后,没有任何东西被添加到向量中,因为它在启动线程后立即执行它。因此,您还可以添加“完整”方法来指示已添加所有车辆。

创建一个表示可运行线程的类,并创建一个可在任何侦听器上调用的“vehicledAdded(Vehicle vehicle)”。

这样的东西(这是关闭袖口而不是编译,所以它可能充满了拼写错误,但它会让你足够接近):

class MyParentClass implements VehicleListener {
  private Vector vehicles = new Vector();

  public MyParentClass() {
    VehicleAdderTask vat = new VehicleAdderTask();
    //add this class as a listener on the task
    vat.addVehicleListener(this);

    //kick the thread off
    Thread t = new Thread(vat);
    t.start();
  }

  @Override
  public void vehicleAdded(Vehicle v) {
    vehicles.add(v);
  } 

  @Override
  public void taskComplete() {
    //output your vehicle list
  }

}

class VehicleAdderTask implments Runnable {
  private List<VehicleListener> listeners = new ArrayList<VehicleListener>();
  public void addVehicleListener(VehicleListener vh) {
    listerners.add(vh);
  }

  public void run() { 
    while(somecondition) {
      Vehicle v = new Vehicle();

      //fire event ot indicate a new vehicle was added.
      for(VehicleListner vl: listeners) {
        vl.vehicleAdded(v);
      }
    }

    //fire task completed on all listeners 
    for(VehicleListner vl: listeners) {
      vl.taskComplete();
    }

  }
}

interface VehicleListener {   
  public void vehicleAdded(Vehicle v); 
  public void taskComplete();
}