Java Android listview正在由多线程更新。您看到一个问题
可能与我之前发布的问题有关,但这是另一种风格。我有一个列表视图,它带有定制的基底,采用Vector(它过去采用ArrayList,但我把它做成Vector,因为我听说它更安全)。问题是,我有两个线程更新这个向量,结果listview在数据集上更新GUI。如何确保不会发生线程问题?我所做的足够吗 基本适配器类的一部分:Java Android listview正在由多线程更新。您看到一个问题,java,android,multithreading,Java,Android,Multithreading,可能与我之前发布的问题有关,但这是另一种风格。我有一个列表视图,它带有定制的基底,采用Vector(它过去采用ArrayList,但我把它做成Vector,因为我听说它更安全)。问题是,我有两个线程更新这个向量,结果listview在数据集上更新GUI。如何确保不会发生线程问题?我所做的足够吗 基本适配器类的一部分: public class MyListAdapter extends BaseAdapter { private Vector<Room> roomList
public class MyListAdapter extends BaseAdapter {
private Vector<Room> roomList;
private Context context;
RoomListAdapter(Context c){
this.context = c;
}
@Override
public int getCount() {
return roomList.size();
}
public void setData(Vector<Room> roomData){
roomList= roomData;
notifyDataSetChanged();
}
@Override
public Object getItem(int number) {
return roomList.get(number);
}
@Override
public long getItemId(int arg0) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// Here I get the Room based on position and update my view
}
}
公共类MyListAdapter扩展BaseAdapter{
专用向量室列表;
私人语境;
RoomListAdapter(上下文c){
this.context=c;
}
@凌驾
public int getCount(){
返回roomList.size();
}
公共无效设置数据(矢量房间数据){
roomList=roomData;
notifyDataSetChanged();
}
@凌驾
公共对象getItem(整数){
返回房间列表。获取(编号);
}
@凌驾
公共长getItemId(int arg0){
返回0;
}
@凌驾
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
//在这里,我根据位置获得房间并更新视图
}
}
同时更新列表的My类具有以下方法:
protected void onCreate(Bundle savedInstanceState) {
roomVect = new Vector<RoomDataExtra>();
mylistAdapter = new MyListAdapter(this);
}
private synchronized void addRoom(Room roomData){
roomVect.add(roomData);
runOnUiThread(new Runnable() {
@Override
public void run() {
myListAdapter.setData(roomVect);
listView.setAdapter(myListAdapter);
}
});
}
创建时受保护的void(Bundle savedInstanceState){
roomVect=新向量();
mylistAdapter=新的mylistAdapter(此);
}
私人房间(房间数据){
roomVect.add(roomData);
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
myListAdapter.setData(roomVect);
setAdapter(myListAdapter);
}
});
}
当然,我的线程多次调用addRoom。因此,在列表更新时,我的thead很有可能会调用它。请注意,传递给列表的向量与从列表中更新的向量相同
你认为上面有问题吗?如果有问题,您建议如何解决?向量实际上并不比这里的任何东西都安全。您需要使用信号量完全阻止所有并发访问。这意味着当某个线程想要更改您的列表时,您需要首先获取一个信号量,然后等待另一个线程完成(完成后放弃该信号量)。您还需要在读取列表的UI端执行此操作,但您必须在读取任何列表之前执行此操作,并在读取完整个列表后将其释放 一种不太复杂的方法是将所有列表更改序列化到UI线程。当想要更改列表的线程需要更改它时,让它向主线程上的处理程序发布Runnable。Runnable将进行实际更改。这样,所有实际的读写操作都将发生在一个线程上。这至少可以避免并发异常,但如果多个索引需要在同一时间进行可视化更改,则无法防止出现问题 如果需要这样做(对多个项目的视觉效果进行同步更改),最好的方法是让更新线程更新列表的深层副本。完成后,将UI正在查看的副本更改为这个新数组,并为更新线程创建一个新的深度副本 TLDR:多线程很难。基于您认为vector确实更安全的事实,您似乎不太了解并发性问题。在尝试使用线程之前,您确实需要学习