我有一个ListView,我想使用来自蓝牙套接字的消息进行更新。 ListView在一个片段中,这没有太大关系。
当我想听从套接字传入的消息(这是一个单独的线程上的锁定机制)并用收到的消息更新ListView时出现问题。
public class FChat extends Fragment {
ArrayList<String> listItems=new ArrayList<String>();
ArrayAdapter<String> itemsAdapter;
....
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//setup list view
ListView messageContainer = (ListView) thisView.findViewById(R.id.btMessagesContainer);
itemsAdapter = new ArrayAdapter<String>(thisView.getContext(), android.R.layout.simple_list_item_1, listItems);
currentAct = getActivity();
Thread test = new Thread() {
public void run() {
try {
currentAct.runOnUiThread(new Runnable() {
@Override
public void run() {
listItems.add("other:" + String.valueOf(times));
try {
String reply = bluetoothConnector.readSingleMessage();
listItems.add("other:" + reply);
itemsAdapter.notifyDataSetChanged();
}
catch (IOException e) {
e.printStackTrace();
}
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
test.start();
}
}
因此,这感觉就像是完全阻塞了UI线程,所以我想runOnUiThread就是阻塞了UI线程。
如果我取出阻塞部分
String reply = bluetoothConnector.readSingleMessage();
并将其替换为String reply = "test"
,它可以正常工作,UI已更新,并且看起来很棒。因此,我的问题是,如何从套接字读取数据并使用其内容更新ListView?
谢谢
最佳答案
显然,它阻止了UI thread
。
您的代码在伪代码中的样子:
Thread {
//there is separate thread
UiThread{
//there is UI thread
blockingOperation()
}
}
换句话说,您当前的线程几乎没有用,因为您在UI线程中执行了阻塞操作。
并且可以肯定地与
String reply = "test"
因为那不阻止操作。
所以要解决根本问题就动
String reply = bluetoothConnector.readSingleMessage();
在单独的线程内:
Thread test = new Thread() {
public void run() {
try {
final String reply = bluetoothConnector.readSingleMessage();
currentAct.runOnUiThread(new Runnable() {
@Override
public void run() {
listItems.add("other:" + String.valueOf(times));
listItems.add("other:" + reply);
itemsAdapter.notifyDataSetChanged();
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};