使用cling库进行upnp发现。每当deviceDiscovered启动时,调用以下代码来更新设备列表,因此调用notifyDataSetChanged
的{{1}}
ViewPager
字段声明
public void deviceAdded(Registry registry, Device device) {
// TODO Auto-generated method stub
super.deviceAdded(registry, device);
String name = device.getDisplayString();
String manufac = device.getDetails().getManufacturerDetails()
.getManufacturer();
if (!manufac.contains("Microsoft")) {
if (!deviceNames.contains(name)) {
if (!devices.contains(device)) {
devices.add(device);
deviceNames.add(name);
Log.e(TAG,"\t\tdevice.size() = "+String.valueOf(devices.size()));
// Log.e(TAG,"Calling notify runnable after adding device "+deviceNames.get(deviceNames.size()-1));
runOnUiThread(notifyAdapterDataChanged);
}
}
}
}
ArrayList/*CopyOnWriteArrayList*/<Device> devices;
ArrayList/*CopyOnWriteArrayList*/<String> deviceNames;
是可运行的,如下所示
notifyAdapterDataChanged
获得以下异常
@Override
public void run() {
if(adapter != null){
adapter.notifyDataSetChanged();
}
}
答案 0 :(得分:3)
首先:在每次之后,您将项目添加到适配器中引用的列表中,您必须调用notifyDataSetChanged
。
在UI线程执行notifyDataChanged
之前添加第二个项目时,通常会发生这种情况。您可以通过使用适配器添加项目来防止这种情况。
如果您希望将项目直接添加到列表而不是适配器,则可以使用互斥锁等待runOnUIThread
完成 - 如下所示:
final Semaphore mutex = new Semaphore(0);
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
mutex.release();
}
});
try {
// wait for the line mutex.release(); to be executed
mutex.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
现在,如果您将一个项目添加到列表并从UI线程开始,则添加项目的线程将等待(通过互斥锁)UI线程完成并通知适配器。这样就可以防止在更新适配器之前附加项目滑入列表的情况。
编辑:另一种解决方案是在UI线程中添加项目。在你的情况下是这样的:
runOnUiThread(new Runnable() {
@Override
public void run() {
devices.add(device);
deviceNames.add(name);
adapter.notifyDataSetChanged();
}
});
这样您就可以避免使用mutex
,同时每adapter.notifyDataSetChanged();
次调用只会添加一项。
答案 1 :(得分:0)
如果你看这里:https://stackoverflow.com/a/5092426/1235505
引用:
对于ArrayAdapter,只有在适配器上使用add(),insert(),remove()和clear()时,notifyDataSetChanged才有效。
因此,如果您手动将设备添加到适配器中的集合中,则修改数据后可能会出现异常。
我无法确定您是否已经在问题中使用这些方法,如果您这样做,请在下次向我们展示字段声明。
答案 2 :(得分:0)
如果您出于某种原因离开了您的活动(例如通过Intent转到其他应用程序),您必须在您的活动中添加以下行。
android:configChanges="keyboardHidden|orientation|screenSize"