我在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。
答案 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();
}