我的应用有聊天功能。当我的应用程序首次启动时,我会生成一个侦听器线程来侦听传入的数据:
public class MainActivity extends AppCompatActivity {
public static LinkedList<Message> chatList;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chatList = new LinkedList<Message>();
Handler listenerThreadHandler = new Handler();
MyListener myListener = new MyListener(listenerThreadHandler, MainActivity.this);
Thread listenerThread = new Thread(myListener);
listenerThread.start();
}
}
我的聊天功能是我主要活动中的片段/标签。它有您查看聊天的标准窗口,以及用于发送聊天的EditText和Button:
<LinearLayout android:id="@+id/chat_window" android:orientation="vertical">
<ListView
android:id="@+id/received_chats"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll">
</ListView>
<LinearLayout android:id="@+id/control_window" android orientation="horizontal">
<EditText android:id="@+id/chat_entry_window" />
<Button android:id="@+id/send_chat_button" android:text="Send" />
</LinearLayout>
</LinearLayout>
当我发送文本时,我将其添加到我的主要LinkedList。
public class Chat extends Fragment {
private View rootView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
rootView = inflater.inflate(R.layout.chat, container, false);
return rootView;
}
@Override
public void onViewCreated(View rootView, Bundle, savedInstanceState){
super.onViewCreated(rootView, savedInstanceState);
displayChats();
}
@Override
public void onResume(){
super.onResume();
displayChats();
}
@Override
public View getView(){
Button sendChatButton = (Button) rootView.findViewById(R.id.send_chat_button);
sendChatButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
EditText chatEntryWindow = (EditText) rootView.findViewById(R.id.chat_text_entry);
// Add the chat to the LinkedList
MainActivity.chatList.add(chatEntryWindow.getText().toString());
}
});
}
public void dispalyChats(){
final ArrayAdapter adapter = new CustomArrayAdapter(getActivity, R.layout.line_of_chat_text, MainActivity.chatList);
final ListView list = (ListView) rootView.findViewById(R.id.received_chats);
list.smoothScrollToPosition(list.getCount() - 1);
}
}
我还在侦听器中将任何传入的聊天添加到应用
public class MyListener implements Runnable {
Handler myHandler;
Context myContext;
public MyListener(Handler myHandler, Context myContext){
this.myHandler = myHandler;
this.myContext = myContext;
}
@Override
public void run(){
listenForChats();
}
public listenForChats(){
// here is where I want to add chats to my main list.
MainActivity.chatList.add(received_chat);
}
}
我希望能够做的是将ListenerThread接收的文本传递回要插入LinkedList的UI线程。我知道我需要这样做,因为我经常在我的应用中遇到这个错误:
java.lang.IllegalStateException
适配器的内容已更改,但listview未收到通知。
确保不从后台线程修改适配器的内容,而只是从UI线程修改。
之前我使用过Handler,但我不知道我是否正确使用它。在过去,我已经传递了一个布局元素(例如,TextView,ImageView等),并使用处理程序更新了它。
在我的监听线程中,我改变了
MainActivity.chatList.add(received_chat);
到
myHandler.post(new Runnable(){
@Override
public void run(){
MainActivity.chatList.add(received_chat);
}
});
我的聊天记录仍然被添加到主链接列表中,但我不知道它与我最初的做法有什么不同。我怎么知道我是否已成功将数据传递回UI线程?
那么,如何正确地将数据从我的侦听器线程传递到UI线程以添加到LinkedList?